【问题标题】:How to keep an object “persistent” in a C# dll?如何在 C# dll 中保持对象“持久”?
【发布时间】:2012-01-05 21:28:45
【问题描述】:

我用 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() 时,连接器对象指向 NULL。

当我从我的 C 代码中调用 Timestep() 时,我必须做什么才能访问之前创建的连接器实例?

我可能完全找错了方向。任何提示都表示赞赏。

【问题讨论】:

  • 请向我们展示您的 C++ 代码。此外,C != C++。
  • 已解决。谢谢大家。感谢 SLaks - 通过我的 C/C++ 代码向您展示它向我展示了错误。 / Stackoverflow 不允许我发布答案,因为我没有收集到足够的声望点。但它会让我在 8 小时内。然后我发布答案。

标签: c# object dll object-persistence


【解决方案1】:

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

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

    };

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

【讨论】:

    【解决方案2】:

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

    所以我将该指针更改为一个实例,一切都很好。感谢您的 cmets!

    【讨论】:

      猜你喜欢
      • 2016-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多