从 C# 调用 C++ dll。 “无法封送'返回值':托管/非托管类型组合无效。”

Posted

技术标签:

【中文标题】从 C# 调用 C++ dll。 “无法封送\'返回值\':托管/非托管类型组合无效。”【英文标题】:Calling C++ dll from C#. "Cannot marshal 'return value': Invalid managed/unmanaged type combination."从 C# 调用 C++ dll。 “无法封送'返回值':托管/非托管类型组合无效。” 【发布时间】:2015-02-09 21:04:22 【问题描述】:

我的头文件。

extern "C"  class MyFuncs

 public:
    __declspec(dllexport) unsigned char PassImage(unsigned char buffer, int size);
;

CPP 文件。

unsigned char MyFuncs::PassImage(unsigned char buffer, int size)

    return buffer;

一切正常,除非我将缓冲区返回到我的主应用程序。

    [DllImport("ExampleDLL.dll", EntryPoint = "?PassImage@MyFuncs@Funcs@@QAEXEH@Z")]
    public static extern byte[] PassImage(byte[] a, int count);

当我将 unsigned char 返回到 byte[] 时发生错误。

如果我将 byte[] 更改为 byte,我会返回一个值,并且没有错误。

这是确切的错误:

无法封送“返回值”:托管/非托管类型无效 组合。

我怎样才能接受将 unsigned char 返回到 byte[]?

【问题讨论】:

您发布的代码示例中的某些内容必须关闭。 unsigned char 不是数组。也许应该是 unsigned char * ? 除了错误使用unsigned char,你不能像这样返回byte[] 我刚把它改成 unsinged char * 还是一样的错误。 我再说一遍,你不能像这样返回byte[]。我们需要了解的是您正在尝试做的事情。您还需要了解unsigned char 是什么。它是一个单一的标量。它不是一个数组。哦,你还有一个实例方法也不好。所以,目前只是一团糟。你需要退后一步,走得更慢,更深入地思考。无论如何,翻来覆去也不会得到你。寻求理解。 【参考方案1】:

unsigned char 应该是 unsigned char * :)

编辑: 您还需要传递数组的长度并将其作为 C# 中的字节指针处理,因为 .NET 不知道它的长度。本文描述:https://***.com/questions/8268625/get-pointer-on-byte-array-from-unman‌​aged-c-dll-in-c-sharp

【讨论】:

__declspec(dllexport) unsigned char * PassImage(unsigned char *buffer, int size);还是一样的错误。 好的,那么您还需要传递数组的长度并将其作为 C# 中的字节指针处理,因为 .NET 不知道字节数组的长度(它实际上是一个指针,但是您想将其用作数组)通过。本文描述:http://***.com/questions/8268625/get-pointer-on-byte-array-from-unmanaged-c-dll-in-c-sharp 您已接受此答案,但这是完全错误的。您不能在 C# 端返回 byte[]。您的非托管函数是具有 thiscall 调用约定的实例方法。 Demangle 到此:public: void __thiscall Funcs::MyFuncs::PassImage(unsigned char,int) 如果需要帮助,请告诉我!! 嗨大卫,我把它改成了无符号字符*。除了当我将 unsigned char * 返回到 C# 时,它不知道长度。 您接受了这个答案。我不知道为什么。它解决了一个问题,但错过了更多。如果你想进步,你需要支持并尝试理解。我没有看到太多的迹象。除非你这样做,否则我无能为力。【参考方案2】:

在 C++ 中,您返回一个 unsigned char,它是一个字节长。在 C# 中,您需要一个字节 array。您可能想从 C++ 返回一个 unsigned char *

【讨论】:

__declspec(dllexport) unsigned char * PassImage(unsigned char *buffer, int size);还是行不通。同样的错误

以上是关于从 C# 调用 C++ dll。 “无法封送'返回值':托管/非托管类型组合无效。”的主要内容,如果未能解决你的问题,请参考以下文章

从 C# 调用带有 C++ 标头的 dll

如何从 c++ 项目中调用用 c# 创建的 dll 文件? [复制]

从 C++ 调用 C# dll

从 C# 调用 C++ dll 并抛出 SEHException

从 C# 调用 C++ dll 函数时出现问题

从 C++ 调用 C# dll(MSVC 编译器)