【问题标题】:Using external C++ library with C#在 C# 中使用外部 C++ 库
【发布时间】:2016-02-23 12:00:07
【问题描述】:

我正在尝试在我的 c# 项目中包含一个外部 C++ 库。 这是我要使用的函数原型:

 unsigned char* heatmap_render_default_to(const heatmap_t* h, unsigned char* colorbuf)

这个函数正在为 colorbuf 分配内存:

colorbuf = (unsigned char*)malloc(h->w*h->h * 4);

Pinvoke:

[DllImport(DLL, EntryPoint = "heatmap_render_default_to", CallingConvention = CallingConvention.Cdecl)]
public static extern byte[] Render_default_to(IntPtr h, byte[] colorbuf);

我尝试在 main 方法中使用这个函数来测试库:

           var colourbuf = new byte[w * h * 4];
        fixed (byte* colourbufPtr = colourbuf)
            HeatMapWrapper.NativeMethods.Render_default_to(hmPtr, colourbuf);

当我尝试这个时,我得到一个分段错误异常。 有人可以帮我解决这个问题吗?

【问题讨论】:

标签: c# c++ .net pinvoke


【解决方案1】:

您将需要手动编组返回值。声明为IntPtr:

[DllImport(DLL, EntryPoint = "heatmap_render_default_to", 
    CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr Render_default_to(IntPtr h, byte[] colorbuf);

您可以使用Marshal.Copy复制缓冲区:

IntPtr buffPtr = Render_default_to(...);
var buff = new byte[w * h * 4];
Marshal.Copy(buffPtr, buff, 0, buff.Length);

您还需要安排外部代码为要返回的非托管内存导出解除分配器。否则你最终会泄漏这个内存。

我假设您设法在Render_default_to 的第一个参数中正确传递了heatmap_t*。我们看不到您的任何代码来做到这一点,而且您也完全有可能犯错。这可能会导致类似的运行时错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 2010-11-20
    相关资源
    最近更新 更多