如何保持对象“持久”在 C# dll 中?

发布于 2024-12-17 21:42:01 字数 1022 浏览 1 评论 0原文

我用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() 时,我必须做什么才能访问之前创建的 Connector 实例?

我可能根本就找错了方向。任何提示表示赞赏。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤城病女 2024-12-24 21:42:01

如果我没记错的话,你想在 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();
        }

    };

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

If I am not wrong you want to maintain a single object throughout the use of dll in c. If that is the case try something similar to singleton pattern.

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

What singleton emphazises is you create only single object for a class and use it to perform all the work you need. Basically you might need a function that does something like this,

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

    };

Even though this is not the traditional way of doing things using singleton but I think it still does the work. I may be wrong. Please correct me if I have misunderstood something.

最好是你 2024-12-24 21:42:01

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

因此我将该指针更改为一个实例,一切都很好。感谢您的评论!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文