0

私は c++ ライブラリで ac# ラッパーを使用しています。呼び出された関数は、クラス オブジェクトへのポインターを返します。C# ラッパーでは、そのメソッドを呼び出すと、インターフェイス変数が返されます。そのインターフェイス変数は null であるため、値を取得できません。値を取得するには、そのインターフェイス変数をどのように処理すればよいですか。誰でも私を助けてください。

以下のコードでは、ROOTNET.Interface.NTH1F がインターフェイスであり、ROOTNET.NTH1F はクラスです。

using ROOTNET.Utility;
using ROOTNET.Interface;

NTH1F g = new ROOTNET.NTH1F("g", "background removal", doubleArrayX.Length - 1,    
    doubleArrayX);

g.SetContent(doubleArrayY);
g.GetXaxis().SetRange(xmin, xmax);

ROOTNET.NTH1F bkg = new ROOTNET.NTH1F(g);
bkg.Reset();

bkg.Add(g.ShowBackground(80, ""));

上記では、バックグラウンドで削除された値が bkg に保存されることを期待していますが、bkg にはすべてゼロが含まれています。バックグラウンドで削除された g の値を bkg に取得するのを手伝ってください。

ShowBackground(int niter, string option)メソッドのコードはどこですか

public unsafe virtual NTH1 ShowBackground (int niter, string option)
{
    NetStringToConstCPP netStringToConstCPP = null;
    NetStringToConstCPP netStringToConstCPP2 = new NetStringToConstCPP (option);
    NTH1 bestObject;
    try
    {
        netStringToConstCPP = netStringToConstCPP2;
        int num = *(int*)this._instance + 912;
        bestObject = ROOTObjectServices.GetBestObject<NTH1> (calli ((), this._instance, niter, netStringToConstCPP.op_Implicit (), *num));
    }
    catch
    {
        ((IDisposable)netStringToConstCPP).Dispose ();
        throw;
    }
    ((IDisposable)netStringToConstCPP).Dispose ();
    return bestObject;
}
4

1 に答える 1

1

C++ から返されたポインター値をインターフェイスとして扱うことはできません (COM インターフェイスでない限り)。C++ と C# のクラスとインターフェイスは、異なる低レベルの構造を持っている可能性があり (ほとんどの場合そうです)、単純に別の構造にキャストすることはできません。

唯一の方法は、ライブラリによって返される C++ クラスの周りに別のラッパーを記述することです。それはそれほど似ていないはずです:

C++/DLL:

__declspec(dllexport) void * ReturnInstance()
{
    return new MyClass();
}

__declspec(dllexport) void MyClass_CallMethod(MyClass * instance)
{
    instance->Method();
}

C#:

[DllImport("MyDll.dll")]
private static extern IntPtr ReturnInstance();

class MyClassWrapper
{
     private IntPtr instance;

     [DllImport("MyDll.dll")]
     private static extern void MyClass_CallMethod(IntPtr instance);

     public MyClassWrapper(IntPtr newInstance)
     {
         instance = newInstance;
     }

     public void Method()
     {
         MyClass_CallMethod(instance);
     }
}

// (...)

IntPtr myClassInstance = ReturnInstance();
MyClassWrapper wrapper = new MyClassWrapper(myClassInstance);
wrapper.Method();

お役に立てれば。

于 2013-05-08T06:08:03.930 に答える