CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Aug 2006
    Posts
    52

    Writing managed C++ dll so unmanaged C++ program can use third party c# dll

    Using Windows 7 and VS 2010 (soon 2015). I’m writing a C++ managed code dll (managed.dll)which will be an intermediary between our unmanaged C++ code (program.exe) and a third party C# driver dll (tcbDriver.dll). I don't have access to the code for tcbDriver.dll. However, in the following example of managed.dll code, I use a TcbDriver class which accesses the tcbDriver.dll. So program.exe "calls __declspec(dllexport) int ConnectTCB()" in managed.dll, which in turns calls Connect() in tcbDriver.dll. It works. The problem is, I don't know how get the managed.dlll code to preserve the same instance of "work" or "tcb" for other methods that program.exe will call. For example, in this case tcbDriver.dll will eventually make tcb.Initialized equal to "true", indicating it is done initializing the hardware. However, managed.dll needs to use the same instance of "work" or "tcb" in another exposed function that it used to call Connect(). The exposed function "__declspec(dllexport) bool IsInitialized()" makes a new instance, so tcbDriver.dll doesn't ever make tcb.Initialized equal to "true", even after TcbDriver is done initializing.

    Code:
    namespace ManagedTCB 
    {          
      public ref class DoWork
      {
           TcbDriver::TCB tcb;          
            public:int ConnectTCB()
           {                                              
               try
               {
                    tcb.Connect();
               }
                   catch(...)
               {
                    return 0;
               }
               return 1;
           }
           public:bool IsInitialized()
           {    
                return tcb.Initialized;
           }
      };
    }
    
    
    __declspec(dllexport) int ConnectTCB()
    {
        ManagedTCB::DoWork work;     
        return work.ConnectTCB();         
    }
    __declspec(dllexport) bool IsInitialized()
    {
        ManagedTCB::DoWork work;     
        return work.IsInitialized();           
    }
    How do I use the same instance of the tcb class in different exported functions? Thanks for any help,
    Gary

  2. #2
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Writing managed C++ dll so unmanaged C++ program can use third party c# dll

    Both functions your wrapper exposes to your unmanaged code instantiate ManagedTCB::DoWork as a local variable which, including its initialization state, is lost as soon as the function returns.

    The straightforward solution to preserve the object between calls is to make it a static global variable. Unfortunately, C++/CLI does not allow global variables of managed types. But as a workaround you can use a public static member variable of a managed class:

    Code:
    private ref class DisguisedGlobal
    {
      public:
        static ManagedTCB::DoWork ^work = gcnew ManagedTCB::DoWork;
    };
    A neater solution would be to make the static instance variable a private member of your managed wrapper class and hide it behind the singleton pattern:

    Code:
    namespace ManagedTCB
    {
      public ref class DoWork
      {
        // ...
    
        public:
          static DoWork ^GetInstance()
          {
            if (!instance)
              instance = gcnew DoWork;
            return instance;
          }
    
        private:
          static DoWork ^instance;
      };
    }
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  3. #3
    Join Date
    Aug 2006
    Posts
    52

    Re: Writing managed C++ dll so unmanaged C++ program can use third party c# dll

    Thank you very much for your thorough answer. I'm finding, however, that by simply declaring the tcb class to be static, that the above code works:

    static TcbDriver::TCB tcb;

    That is, I'm able to have different exported methods each with a new instance of the DoWork class that access the same tcb class. It seems to work!

    Thanks again,
    Gary

  4. #4
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Writing managed C++ dll so unmanaged C++ program can use third party c# dll

    That static only approach should work if, instead of creating it locally and instantly discarding the TCB object, you create it only once and preserve it in a static member variable.

    If you connect to something, you'll likely want to do something with whatever you connected to. And in order to to that, you need the connection, which is represented by the TCB object. The best you can achieve without preserving the TCB object is to create a new connection for each and every action you want to perform on whatever that driver DLL is for. If that would even work at all, it would at least be quite unelegant.

    The static only approach with the preserved TCB object would technically be rather similar to the singleton approach I outlined, but a bit more compact. However, keeping your DoWork class with the TCB instance member may be beneficial if you plan to support more than one simultaneous connection anytime in the future.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured