3

私は C# で dll を作成し、使用するクラスを提供しています。dll は、私が作成した C プログラムによって呼び出されます。(これは一部のプログラムのプラグインです。プラグインのコードは C で記述しなければなりませんが、.NET の機能を使用したいため、dll を使用したいと考えています)。

dll では、ストリームを開き、dll への 2 つの呼び出し間で永続化する必要があるその他の処理を実行したいと考えています。これは、プライベート メンバー コネクタによって次のコードで表されます。

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 の作成前のインスタンスにアクセスできるようにするにはどうすればよいですか?

私はおそらくまったく間違った方向に検索します。どんなヒントでも大歓迎です。

4

2 に答える 2

0

私が間違っていなければ、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();
        }

    };

これはシングルトンを使用して物事を行う従来の方法ではありませんが、それでも機能すると思います。私は間違っているかもしれません。私が何かを誤解している場合は、私を修正してください。

于 2011-11-24T19:42:35.390 に答える
0

私の C/C++ コードを求めてくれた SLaks に感謝します。そこに問題がありました。思ったより簡単でした。表示するコードをまとめているときに間違いを見つけました。


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
}

その行で 2 番目のインスタンスを要求していることに気付きました

IEPAccessPtr pIEPAccess(__uuidof(EPAccess));

そのため、そのポインターを 1 つのインスタンスに変更しましたが、すべて問題ありません。コメントしてくれてありがとう!

于 2011-11-25T08:10:41.020 に答える