2017-09-27 199 views
-2

我想從c#調用非託管C++,但收到關於返回值的異常。 例外:從非託管C++ dll到c返回一個字符串#

System.Runtime.InteropServices.MarshalDirectiveException:「無法編組‘返回值’:無效託管/非託管類型組合(數組只能封送LPArray,ByValArray,或安全數組)。」

我有一個類似的功能,看起來沒有返回值(無效),沒有任何問題的工作。

我將C++項目的平臺(編譯器)設置爲v100(Visual Studio 2010),並在c#項目中使用.net 4.5。

C++項目創建了一個lib + dll文件,我將它們放在可執行文件夾中。

當我嘗試更換返回值是「字符串」的C#代碼,異常轉換爲:

System.AccessViolationException:「試圖讀取或寫入保護內存。這往往表明其他內存已經損壞。「

當我刪除的返回值函數性質([return: MarshalAs(UnmanagedType.BStr)])我收到以下異常:

System.Runtime.InteropServices.MarshalDirectiveException:「不能元帥返回值「:無效的託管/非託管類型組合。'

而當我做的組合:刪除返回值函數屬性和轉換返回類型爲字符串,應用程序只是關閉自己沒有捕獲任何異常。

C++代碼

extern "C" 
{ 
    ExternalDll_API char* FuncA(char* projectId); 
} 

ExternalDll_API char* FuncA(char* projectId) 
{ 
    return "abc"; 
} 

C#代碼

[DllImport("ExternalDll.dll")] 
[return: MarshalAs(UnmanagedType.BStr)] 
public static extern char[] FuncA(string projectId); 

var key = FuncA(projectId.ToString()); 
+0

https://stackoverflow.com/questions/10799685/how-to-pass-strings-from-c-sharp-to-c-and -from-c-to-c-using-dllimport –

+0

這不是完全重複的,建議的答案基於1--知道返回的字符串的大小,2-傳遞一個StringBuilder並從C++代碼中填充它,而不是直接返回一個字符指針。 – Gusman

回答

1

要接收空值終止字符串從C++ DLL,你可以這樣做:

1 - 更改返回類型IntPtr

[DllImport("ExternalDll.dll")] 
public static extern IntPtr FuncA(string projectId); 
使用Marshal

2-檢索從指針串:

var result = FuncA(someString); 
var strResult = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(result); 
相關問題