2011-06-14 74 views
6

儘管我對C++有相當的經驗,但在C#中我仍然是初學者。我目前的項目需要我在C++ DLL和C#GUI之間來回傳遞數據。我主要通過閱讀stackoverflow上的響應來學習如何做到這一點。不幸的是,我遇到了一個讓我相當困難的問題。該DLL使用g ++(gcc版本4.2.1 mingw32-2)進行編譯,並使用Visual Studio 2010構建GUI。在C++ DLL和C#之間傳遞數據時的結果不一致

我的問題是,我可以從一些DLL函數,而不是其他人的數據到C#。令人生氣的是,它似乎不一致,因爲一些功能起作用,而另一些則不起作用。爲了向您展示我的意思,我在下面包含了C#導入代碼和C++導出聲明。我真的很感激這方面的一些建議,因爲我真的被困在如何解決這個問題上。

此功能工作正常:

[DllImport("mstTools.dll", EntryPoint = "mstLastError", CallingConvention = CallingConvention.Cdecl)] 
private static extern IntPtr LastError(); 

public static string mstGetLastError() 
{ 
    return Marshal.PtrToStringAnsi(LastError()); 
} 

它宣佈這樣的DLL頭:

extern "C" __declspec(dllexport) const char* mstLastError(); 

此功能不起作用,並返回一個空字符串:

[DllImport("mstTools.dll", EntryPoint = "mstGetMetadata", CallingConvention = CallingConvention.Cdecl)] 
private static extern IntPtr GetMetadata([MarshalAs(UnmanagedType.LPStr)]string StgMapName); 

public static string mstGetMetadata(string StgMapName) 
{ 
    return Marshal.PtrToStringAnsi(GetMetadata(StgMapName)); 
} 

它在DLL中聲明如下:

extern "C" __declspec(dllexport) const char* mstGetMetadata (char* CStgMapName); 

使用Visual Studio調試器,我可以看到導入的DLL函數(GetMetadata)返回null。

相反,返回布爾工作,例如功能:

[DllImport("mstTools.dll", EntryPoint = "mstMapExists", CallingConvention = CallingConvention.Cdecl)] 
[return: MarshalAs(UnmanagedType.I1)] 
public static extern bool mstMapExists([MarshalAs(UnmanagedType.LPStr)]string StgMapName); 

被聲明爲在DLL如下:

extern "C" __declspec(dllexport) bool mstMapExists (char* CStgMapName); 

此功能的工作原理完全如我所料,因爲它的回報它應該是真/假。

但返回雙返回NaN功能:

[DllImport("mstTools.dll", EntryPoint = "mstGetResolution", CallingConvention =CallingConvention.Cdecl)] 
[return: MarshalAs(UnmanagedType.R8)] 
public static extern double mstGetResolution([MarshalAs(UnmanagedType.LPStr)]string StgMapName); 

這是在DLL的聲明:

extern "C" __declspec(dllexport) double mstGetResolution (char* CStgName); 

任何想法發生了什麼?

感謝和問候,麥克

+0

做一個測試C++程序並調用從C++這些方法,看看他們做同樣的事情。我通常會這樣做一個理智檢查,以確保我沒有忘記一些初始化或導致這些方法按照它們的方式工作的東西。 – Nathan 2011-06-14 05:14:52

+0

pinvoke編組器假定MSVC ABI。這與GCC ABI不一樣。 – 2011-06-14 07:18:06

回答

1
[DllImport("mstTools.dll", EntryPoint = "mstGetResolution")] 
public static extern decimal mstGetResolution([In]string StgMapName); 

[DllImport("mstTools.dll", EntryPoint = "mstGetMetadata")] 
private static extern IntPtr GetMetadata([In]string StgMapName);