如何在c# dll中保持对象的“持久性”

本文关键字:持久性 对象 dll | 更新日期: 2023-09-27 18:15:53

我用c#写了一个dll,提供了一个类供使用。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。

我要做什么,当我从我的C代码调用Timestep(),我可以访问之前创建的连接器实例?

我可能找错方向了。

如何在c# dll中保持对象的“持久性”

如果我没有错,你想在c中使用dll的整个过程中维护一个对象。如果是这种情况,尝试类似于单例模式的东西。

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

singleton强调的是你只为一个类创建一个对象,并使用它来执行你需要的所有工作。基本上你可能需要一个这样的函数

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();
        }
    };

尽管这不是使用单例的传统方式,但我认为它仍然可以工作。我可能错了。如果我误解了什么,请纠正我。

感谢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));

所以我把指针改成了一个实例,一切都好了。谢谢你的评论!