Search code examples
c#objectdllobject-persistence

How to keep an object “persistent” in a C# dll?


I have written a dll in C#, offering a class for use. The dll is called by a C program that I have written. (It’s a plugin to some program. I have to write the plugin’s code in C, but I want to use the functionality of .NET, therefore the dll).

In the dll, I want to open up a stream and do other stuff that should be persistent between two calls to the dll. That is represented in the following code by the private member Connector.

namespace myCSharpDll
{
    // the c++ program calls this methods
    public interface IAccess
    {
        double Initialize();
        double Timestep(double time, double[] values);
        ...
    }

    // E is the beginning of another program my dll should connect to, therefore the names
    public class EAccess : IAccess
    {
        // EConnector is another class I defined in the same dll
        private EConnector Connector;

        public double InitializeE()
        {
            Connector = new EPConnector();
        }
        public double Timestep(double time, double[] values)
        {
            return Connector.Connect();
        }

When I make a call to InitializeE() and later one to Timestep() the Connector oject points to NULL.

What do I have to do that when I call Timestep() from my C code, that I can access the before created instance of Connector?

I probably search in the wrong direction at all. Any tips are appreciated.


Solution

  • Thanks SLaks for asking for my C/C++ code. That is where the problem was located. It was simpler than I thought. I found the mistake while putting together the code to show you.


    I know that C and C++ is not the same, the plugin structure is just a little weird. Most of the code was generated by a wizard. I just had to fill in my code. It's a cpp file, but the code seems to be C. Well, I think that is off topic.

    Here it is, I extraced the most important lines.

    // the dll is connected via COM, using the type library file that regasm generated
    #import "[path]\myCSharpDll.tlb" raw_interfaces_only
    using namespace myCSharpDll;
    
    static void OnActivate (IfmDocument, Widget);
    
    //off topic: this are the weird lines the wizard put in my way 
    #ifdef __cplusplus
    extern "C"
    #endif /* __cplusplus */
    
    // when the plugin is called by the host program, this function is called
    static void OnActivate (IfmDocument pDoc, Widget button)
    {
        InitializeIntermediate(pDoc);
        Timestep1(...);
    }
    
    static void InitializeIntermediate(IfmDocument pDoc)
    {
        // Initialize COM.
        HRESULT hr = CoInitialize(NULL);
        IEPAccessPtr pIEPAccess(__uuidof(EPAccess));
    
        double result = -1;
        pIEPAccess->InitializeEP (&result);
    
        ...
    }
    
    static void Timestep1(...)
    {
        IEPAccessPtr pIEPAccess(__uuidof(EPAccess));
    
        double result = -1.1;
        pIEPAccess->Timestep (...);
        ...
    
        // now I get a wrong result back here, because this call leads to nowhere as
        // the connector object in the dll is void
    }
    

    I realized that I am requesting a second instance with that line

    IEPAccessPtr pIEPAccess(__uuidof(EPAccess));
    

    So I changed that pointer to one single instance and everything is fine. Thanks for your comments!