Jump to content

DLL Heck

- - - - -

  • Please log in to reply
8 replies to this topic

#1
PGP_Protector

PGP_Protector

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 253 posts
From the C# Side, Original Thread.
Link to C# Thread about this --> http://forum.codecal...html#post255245

I apparently need to rewrite my DLL in C++ so the person using the DLL can use it in their development environment (Visual C++ 6.0)

Now my C++ skills are about as close to noob as you can get but I can manage a few simple things.

The basic problem I've got right now is learning how to define my Functions / Commands

Example the User (in the C# Version ) Has two Commands

  • public static int SendConfig(string[] TestConfigurationReceived)
  • public static double[,] RunTest(int TestParamater1,int TestParamater2)
with the Code to Either Get The Users Configuration, or Run the Test defined for the Commands in C#, This works as expected.

Now to Do This In C++ I've got 2 Files the MyDLL.cpp & the MyDLL.h Files (Pulled from a "Create a DLL in C++ Demo I found)

They have their functions "Defined" in the .h file like this.

  • static __declspec(dllexport) double Divide(double a, double b);
Then in the .cpp file like this
    double MyDLL::Divide(double a, double b)
    {
        if (b == 0)
        {
            throw new invalid_argument("b cannot be zero!");
        }

        return a / b;
    }
So How do I define it in the .h file to receive an unknown size array, and return an unknown size array in the .H & .CPP Files ?

#2
PGP_Protector

PGP_Protector

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 253 posts
This is feeling so Backwards to me..

This is a simplified version of the DLL i made -> http://www.pgp-prote.../help/MyDLL.zip

using System.IO;
using System.IO.Pipes;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;

namespace PGPDLL
{
    public class MyDLL
    {
        private static bool ValidComPort = false;
        private static bool ValidConfig = false;
        private static StreamWriter MyWriter;
        private static StreamReader MyReader;
        private static NamedPipeClientStream MyIPCPipe;
        /// <summary>
        /// Returns Last Recorded Error Encountered by the DLL.
        /// </summary>
        public static string InternalErrorReason = "No Error Default";
        private static string[] TalkPipeOut()
        {
            try
            {
                if (MyIPCPipe.NumberOfServerInstances > 0)
                {
                    string temp;
                    temp = MyReader.ReadLine();
                    return temp.Split(':');
                }
                else
                {
                    return null;
                }
            }
            catch
            {
                return null;
            }

        }
        private static bool TalkPipeIn(int ComType, string ComData)
        {
            bool ValidPipeIn = true;

            try
            {
                MyWriter.Write(ComType);
                MyWriter.Write(ComData);
            }
            catch
            {
                ValidPipeIn = false;
            }
            return ValidPipeIn;
        }
        private static void CheckServerOpen(int ServerProcessID)
        {
            bool ActiveServer = true;
            try { ActiveServer = !Process.GetProcessById(ServerProcessID).HasExited; }
            catch { ActiveServer = false; }
            // If ActiveServer = False, 
            if (ActiveServer == false)
            {
                ValidComPort = false;
                System.Windows.Forms.MessageBox.Show("Lost Connection To Tester!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                MyIPCPipe.Close();
            }
        }
        static void CheckTimer(object ProcessWatchID)
        {
            int CheckID = (int)ProcessWatchID;
            while (ValidComPort)
            {
                Thread.Sleep(200);
                CheckServerOpen(CheckID);
            }
        }
        private static bool MyWrite(string QstDataOut)
        {
            bool ValidPipeOut = false;
            if (ValidComPort)
                try
                {
                    // Send Data
                    {
                        MyWriter.AutoFlush = true;
                        MyWriter.WriteLine(QstDataOut);
                    }
                    ValidPipeOut = true;
                }
                catch
                {
                    ValidPipeOut = false;
                }
            return ValidPipeOut;
        }
        private static string MyRead()
        {
            // Try to open connection with QST Client Pipe Out
            // QstRead is used for Getting Data From the Client
            string QstReadData = "";
            if (ValidComPort)
                try
                {
                    QstReadData = MyReader.ReadLine();
                }
                catch
                {
                    QstReadData = "";
                }
            return QstReadData;
        }
        /// <summary>
        /// Call to Initilize Comunication with the Server Application
        /// </summary>
        /// <returns>True if Connected, False if Unable to Connect</returns>
        public static bool ServerOpen()
        {
            if (ValidComPort == false)
            {
                MyIPCPipe = new NamedPipeClientStream(".", "MySystemsPipe", PipeDirection.InOut, PipeOptions.Asynchronous);
                ValidComPort = true;
                try { MyIPCPipe.Connect(1000); }
                catch (Exception ex)
                {
                    string Erroris;
                    Erroris = ex.Message;
                    if (Erroris == "Already in a connected state.")
                    {
                        // We're Already Connected, Ignore this error.
                        ValidComPort = true;
                    }
                    else
                    {
                        ValidComPort = false;
                        MessageBox.Show(Erroris);
                    }
                }
            }

            //QstIPCPipe.Close();

            if (ValidComPort)
            {
                int ServerProcessID = 0;
                Thread WatchdogTimer = new Thread(CheckTimer);
                string ClientProcessID = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
                MyReader = new StreamReader(MyIPCPipe);
                MyWriter = new StreamWriter(MyIPCPipe);
                ValidComPort = MyWrite(ClientProcessID);
                ServerProcessID = Convert.ToInt16(MyRead());
                WatchdogTimer.IsBackground = true;
                WatchdogTimer.Start(ServerProcessID);
            }
            return ValidComPort;
        }
        /// <summary>
        /// Used to Send String array to Server for configurations
        /// </summary>
        /// <param name="QstTestConfiguration">String Array of Configuration</param>
        /// <returns>-1 if Error, Or Total Count of Processed Lines</returns>
        public static int QstSendConfig(string[] TestConfigurationReceived)
        {
            string[] QstTestConfiguration = TestConfigurationReceived;
            int FinalValidConfigLines = QstTestConfiguration.Length;
            if (ValidComPort && QstTestConfiguration != null)
            {
                ValidConfig = true;
            }
            else
            {
                InternalErrorReason = "Comunication with Server Not Open";
            }
            return FinalValidConfigLines;
        }
        /// <summary>
        /// Runs a QST Test (Fixed I or Psudo V)
        /// Returns a Double Array for Test Results in the Format of double[Sample#,(0=Magnet,1=Test1,2=Test2,3=Test3,4=Test4)]
        /// </summary>
        /// <param name="TestID1">Calls TestID1 in Configuraton</param>
        /// <param name="TestID2">Calls TestID1 in Configuraton</param>
        /// <returns>double[TestCount,TestID]</returns>
        public static double[,] RunTest(int TestID1, int TestID2)
        {
            string QstTestSequence = "DummyData";
            if (ValidConfig & ValidComPort)
            {
                if (MyWrite("RUNQST") && MyWrite(QstTestSequence))
                {
                    if (MyRead() == "OK")
                        return null;
                    else
                        return null;
                }
            }
            if (!ValidConfig) InternalErrorReason = "No Valid Configuration Test Not Run";
            if (!ValidComPort) InternalErrorReason = "Server Not Found, Test Not Run";
            return null;
        }
        /// <summary>
        /// Request And Returns Server Status or what the Last Recorded Error was
        /// </summary>
        public static string MySystemStatus()
        {
            string TempStatus = "";
            if (!ValidConfig) TempStatus = "No Valid Config ";
            if (ValidComPort)
            {
                if (MyWrite("GETSTATUS"))
                {
                    return TempStatus + MyRead();
                }
            }
            return "Unable to Comunicate";
        }
    }
}

Compiled in C# Visual studio 2010

It works as I wanted (Full version has more functions, but this version has the .NET Functions that's giving the client the problems)

How do I get it so they can Load this DLL in Visual C++ 6.0 ?

#3
PGP_Protector

PGP_Protector

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 253 posts
Will that above DLL even work under C++ 6.0 as written ?

#4
Ancient Dragon

Ancient Dragon

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 400 posts
My guess is that your DLL will not work with VC++ 6.0 because that compiler is just too old and non-standard.

BTW: Its DLL Hell, not Heck. :cursing:
Visit Grandpa's Forums, a social networking forum, with family-oriented arcade games, blogs, discussion forums, and photo albums.

#5
PGP_Protector

PGP_Protector

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 253 posts

Ancient Dragon said:

My guess is that your DLL will not work with VC++ 6.0 because that compiler is just too old and non-standard.

What can I do to make it work with VC++ 6.0
As the Client Refuses to upgrade (There programmer had a year to do the upgrade & says they can't upgrade)


Ancient Dragon said:

BTW: Its DLL Hell, not Heck. :cursing:
Just trying to keep it clean :)

I'd get in trouble if I really wrote What I think of their programmer :D

#6
Ancient Dragon

Ancient Dragon

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 400 posts
>>What can I do to make it work with VC++ 6.0
Rewrite the DLL in either C or C++ with that compiler. AFAIK NO c++ compiler will be able to use that DLL written in C# because c++ doesn't know how to call C# functions/classes. That's why all Microsoft DLLs (except of course MFC dlls) are written in C and not c++.
Visit Grandpa's Forums, a social networking forum, with family-oriented arcade games, blogs, discussion forums, and photo albums.

#7
PGP_Protector

PGP_Protector

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 253 posts

Ancient Dragon said:

>>What can I do to make it work with VC++ 6.0
Rewrite the DLL in either C or C++ with that compiler. AFAIK NO c++ compiler will be able to use that DLL written in C# because c++ doesn't know how to call C# functions/classes. That's why all Microsoft DLLs (except of course MFC dlls) are written in C and not c++.

Ok, I'm able to use my DLL in C++ 2010 -> http://www.pgp-prote...lp/UseMyDLL.zip
sample Project that Opens / Uses the DLL and attempts to communicate via the pipes (if the other app was running, that part even works)

So how is it that I can do it in C++ 2010 but not C++ 6.0

#8
Ancient Dragon

Ancient Dragon

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 400 posts
Because C# language was created a lot of years after c++ 6.0. That version of the compiler knows nothing about .NET framework.
Visit Grandpa's Forums, a social networking forum, with family-oriented arcade games, blogs, discussion forums, and photo albums.

#9
PGP_Protector

PGP_Protector

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 253 posts
Well I found a few lines I needed to get the C# DLL to compile for C++ 6.0, Got VC to Load it, but it didn't like a few things, but I'm 3/4 the way there.
Now it's looking like I've got to change my String Arrays or Arrays and Arrays of Doubles ect that were being returned.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users