2013-05-08 26 views
0

我在C++庫中使用c#封裝,被調用的函數返回一個指向類對象的指針。 在c#包裝中,如果我調用該方法,它將返回一個接口變量。 該接口變量爲空,所以我無法獲取值。 我應該如何處理該接口變量以獲取值。 任何人都請幫助我。如何通過方法將返回的接口變量轉換爲對象?

在下面的代碼,我們有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, "")); 

在上述進出口期待backgroung除去值被保存在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; 
} 
+0

我不同意近距離投票。這是_specific_,但不是_local_。即使不太可能,我也可以看到未來訪問者再次詢問這個問題。請提供投票的理由,以便將來結束問題。 – 2013-05-08 05:20:04

+0

任何人都請幫助我,對不起,如果我沒有正確地問這個問題,我是一個學習者。 – UserCSharp 2013-05-08 05:24:27

+0

請提供您嘗試過的一些示例。代碼,就是。 – 2013-05-08 05:24:58

回答

0

你不能把在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(); 

希望這有助於。

+0

感謝您的示例 – UserCSharp 2013-05-08 06:17:40

+0

,但這裏既沒有C++ dll的源代碼,也沒有c#包裝dll – UserCSharp 2013-05-08 06:20:58

+1

如果C++返回一個類或接口,那麼您肯定應該至少有頭文件。如果是這樣,你可以將DLL包裝在你自己的DLL中,爲你的C++包裝器編寫一個C#包裝器,這應該可以工作。但是,請確保您在取消該項目之前對DLL和P/Invoke機制有足夠的瞭解,因爲它看起來似乎從我讀到的內容中判斷出了一點。 – Spook 2013-05-08 06:33:36

相關問題