2017-09-27 129 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); 
相关问题