2013-08-28 66 views
-1

我對C++很新,所以我可能會在這方面出現一些錯誤。 於是我開始寫一個簡單的C++函數將包含結構作爲返回類型:將包含struct的C++函數傳遞給C#並將其轉換爲具有Marshal.PtrToStructure的c#函數

我的C++結構:

struct a { 
    int i; 
}; 

在library.h文件我的C++函數聲明:

extern "C" __declspec(dllexport) struct a retNumber(); 

我library.cpp文件中的C++函數描述:

struct a retNumber() 
{ 
    struct a r = a(); 
    r.i = 22; 
    return r; 
} 

所以我只是想編譯它,然後在C#代碼中使用它,我得到下面的編譯錯誤:

error C2371: 'retNumber' : redefinition; different basic types 
error C2526: 'retNumber' : C linkage function cannot return C++ class 
error C2556: 'a retNumber(void)' : overloaded function differs only by return type from 'void retNumber(void)' 

這是我的問題的第一部分,如果你們能幫助我解決這個問題,我會很感激它,一旦它解決了,我要聲明相同的結構在我的C#代碼:

struct a1 
{ 
    int i; 
} 

然後我要導入我的C++函數:

[DllImport("library.dll")] 
public static extern a1 retNumber(); 

一旦完成,我將創建GCHandle:

a1 test = retNumber(); 
GCHandle handle = GCHandle.Alloc(test, GCHandleType.Pinned); 

,然後我會嘗試轉換我的實際結果,並釋放內存:這個時候,我應該有對象,它是A1型的,幷包含變量i值爲22

 Object temp = Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(a1)); 
     handle.Free(); 

所以

如果任何人都可以請通過這個過程delagate我將不勝感激! 非常感謝您提前!

+0

我真的建議,如果你有兩個問題,你問他們兩個分開。 –

+0

他們是互相依賴的,而C++的人將能夠看到我在找什麼 – inside

回答

1

在C++的一面,你需要在extern "C"包一切,包括結構:

extern "C" { 
    struct a { 
     int i; 
    }; 
}; 

在C#的一面,你需要正確指定調用約定:

[DllImport("library.dll", CallingConvention=CallingConvention.Cdecl))] 
public static extern a1 retNumber(); 

一旦你這樣做,就不需要撥打Marshal.PtrToStructure。只是做:

a1 test = retNumber(); 
Console.WriteLine(a1.i); // Should print 22 
+0

謝謝你的答案裏德,如果你可以簡要解釋在哪些情況下我需要使用Marshal.PtrToStructure會很好,謝謝 – inside

+0

好了,所以我包裝了結構,但是編譯器仍然抱怨我的函數:struct a retNumber() {0} {0}結構ar = a(); r.i = 22; return r; } – inside

+0

@Stanislav現在有什麼錯誤? –