将字符串从非托管 c++ dll 返回到 c# [重复]

问题描述 投票:0回答:1

我试图从 c# 调用非托管 c++,但收到有关返回值的异常。 例外:

System.Runtime.InteropServices.MarshalDirectiveException:“无法封送‘返回值’:无效的托管/非托管类型组合(数组只能封送为 LPArray、ByValArray 或 SafeArray)。”

我有一个类似的函数,看起来相同,没有返回值(void),可以正常工作,没有任何问题。

我将c++项目的平台(编译器)设置为v100(Visual Studio 2010)并在c#项目中使用.net 4.5。

c++ 项目创建了一个 lib+dll 文件,我将它们都放在可执行文件夹中。

当我尝试在 C# 代码中将返回值替换为“String”时,异常转换为:

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());
c# c++ com marshalling
1个回答
11
投票

要从 C++ dll 接收以 null 结尾的字符串,您可以执行以下操作:

  1. 将返回类型更改为

    IntPtr

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

    从指针检索字符串
    var result = FuncA(someString);
    var strResult = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(result);
    
© www.soinside.com 2019 - 2024. All rights reserved.