c# - 将字节数组从 C++ 调用到 C#

标签 c# c++ pinvoke

我正在尝试将在 C++ 中创建的字节数组移动到 C# 以供使用,现在我发现字节数组在 C++ 端有效,但当我返回 C# 时返回 null。

C++代码

__declspec(dllexport) void test(unsigned char* t_memory, int* t_size)
{
    int width, height, channels_in_file;
    t_memory = stbi_load("test.png", &width, &height, &channels_in_file, 0);
    *t_size = width*height;
}

C#代码

[DllImport(DllFilePath, EntryPoint = "test", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern int _test(ref IntPtr memory, out int size);

public static void Test()
{   
    IntPtr memory = IntPtr.Zero;
    _test(ref memory, out int size);

    byte[] memoryArray = new byte[size];

    Marshal.Copy(memory, memoryArray, 0, size);

    Bitmap bmp;
    using (var ms = new MemoryStream(memoryArray))
    {
        bmp = new Bitmap(ms);
    }

    bmp.Save("test_recreated.png");
}

最佳答案

C++ 代码不返回数组,因为参数声明不正确。您传递了指针,但需要传递指针的地址。

C++ 代码应该像这样更改以匹配 C# 代码:

__declspec(dllexport) int test(unsigned char** t_memory, int* t_size)
{
    int width, height, channels_in_file;
    *t_memory = stbi_load("test.png", &width, &height, &channels_in_file, 0);
    *t_size = width*height;
    return 0;
}

您必须传递数组的地址,而不是数组本身。请注意此更改后与 size 参数设置的相似性。

我还包含一个返回值以匹配 C# 代码。

您还需要导出一个解除分配器以避免泄漏此内存。

关于c# - 将字节数组从 C++ 调用到 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44751081/

相关文章:

c++ - 客户端主题列表的数据结构

java - 通过 JNI 执行 OpenCV native 函数的问题

.net - 与所有网络计算机通信,无论 IP 地址如何

c# - 遍历 IEnumerable<object>

c# - 在 C# 中是 bool 读/写原子

c++ - 为什么会这样编译?期待 "cannot assign a constant to a non-const reference"

在 32 位和 64 位 Linux 中使用 long 的 C# pInvoke :

c# - 在 "managed-to-native transition"期间到底发生了什么?

c# - 使用 WPF 应用程序替换桌面

c# - 具有流畅验证集合的自定义消息