Как сохранить объект «постоянным» в C # DLL? - PullRequest
3 голосов
/ 24 ноября 2011

Я написал dll на C #, предлагая класс для использования.DLL вызывается программой на C, которую я написал.(Это плагин для какой-то программы. Я должен написать код плагина на C, но я хочу использовать функциональность .NET, поэтому DLL).

В DLL, я хочу открытьпоток и делать другие вещи, которые должны быть постоянными между двумя вызовами в DLL.Это представлено в следующем коде закрытым членом 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();
        }

Когда я вызываю InitializeE (), а затем один раз Timestep (), объект Connector указывает на NULL.

Что мне нужно сделать, когда я вызываю Timestep () из своего кода C, чтобы я мог получить доступ к ранее созданному экземпляру Connector?

Я, вероятно, вообще ищу в неправильном направлении.Любые советы приветствуются.

Ответы [ 2 ]

0 голосов
/ 25 ноября 2011

Спасибо SLaks за запрос моего кода C / C ++. Вот где проблема была найдена. Это было проще, чем я думал. Я обнаружил ошибку при составлении кода, чтобы показать вам.


Я знаю, что C и C ++ - это не одно и то же, структура плагина немного странная. Большая часть кода была сгенерирована мастером. Я просто должен был заполнить мой код. Это файл cpp, но код вроде C. Ну, я думаю, это не по теме.

Вот, я выделил самые важные строки.

// 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
}

Я понял, что запрашиваю второй экземпляр с этой строкой

IEPAccessPtr pIEPAccess(__uuidof(EPAccess));

Так что я изменил этот указатель на один экземпляр, и все в порядке. Спасибо за ваши комментарии!

0 голосов
/ 24 ноября 2011

Если я не ошибаюсь, вы хотите поддерживать один объект на протяжении всего использования DLL в c.Если это так, попробуйте что-то похожее на шаблон синглтона.

http://en.wikipedia.org/wiki/Singleton_pattern

Единственное, что подчеркивает, - вы создаете только один объект для класса и используете его для выполнения всей необходимой работы.По сути, вам может понадобиться функция, которая выполняет что-то вроде этого:

public class EAccess : IAccess
    {
       private static EConnector Connector
        public EConnector getConnector(){
           if(Connector == null){
               Connector = new EConnector();
            } 
             return Connector;
        }
       public double Timestep(double time, double[] values)
        {
          return getConnector().Connect();
        }

    };

Даже если это не традиционный способ работы с использованием синглтона, но я думаю, что он по-прежнему работает.Я могу ошибатьсяПожалуйста, поправьте меня, если я что-то не так понял.

...