如何P /调用分配并返回指向新数组的指针的函数

之字形

我有一个C函数,想从C#程序中调用。函数压缩输入的字节数组并输出新的压缩数组。看起来像这样:

extern __declspec(dllexport) int Compress(chandle handle, 
unsigned char *inputBuf, unsigned char **outputBuf, unsigned long *outputSize);

我已经将其翻译成C#部分。但是output我得到的是一个项目的数组。

[DllImport("compresslib.dll", CallingConvention = CallingConvention.Cdecl)]
internal extern static int Compress(IntPtr handle, byte[] input, out byte[] output, out uint outputSize);

我应该怎么做才能使它正常工作?

这是我在Hans Passant的帮助下能够编写的工作代码

[DllImport("compresslib.dll", CallingConvention = CallingConvention.Cdecl)]
internal extern static int Compress(IntPtr handle, byte[] input, out IntPtr output, out uint outputSize);

// and this is how i call it 
byte[] outputData;
int outputDataSize;
IntPtr outputDataP = IntPtr.Zero;
try
{
    int success = NativeMethods.Compress(handle,
    inputData, out outputDataP, out outputDataSize);
    if (success == -1)
    {
        throw new Exception("Compression failed.");
    }
    outputData = new byte[outputDataSize];
    Marshal.Copy(outputDataP , outputData , 0, (int)outputDataSize);
}
finally
{
    if (outputDataP != IntPtr.Zero)
    NativeMethods.tjFree(outputDataP);// release unmanaged buffer
}

return outputData ;
汉斯·帕桑特
  ..., unsigned char **outputBuf, ...

这个函数有一个非常严重的问题,它也不能从C程序可靠地调用。调用方需要在使用后释放输出缓冲区。这需要使用与C代码中使用的分配器完全相同的分配器。这在C程序中很难保证,而且经常会出错。就像DLL的用户未使用与您使用的完全相同的编译器版本一样。他将使用另一种版本的C运行时库,该版本使用自己的堆。因此,由于他没有使用的堆的句柄,因此无法释放缓冲区。

当您单击时,它几乎变成不可能,CLR当然完全不知道您使用的C运行时版本,并且由于它具有自己的私有副本,因此保证不会使用与您使用的相同的C运行时版本。

您仅得到一个字节的原因与此问题有关,pinvoke marshaller不知道数组有多大,因为它没有创建数组。这是可解决的,您需要将[MarshalAs(UnmanagedType.LPArray),SizeParamIndex = 3]属性应用于参数。这告诉pinvoke编组,第4个参数包含数组的大小。

您将需要解决内存管理问题,因此无法解决问题,因为在pinvoke编组尝试释放阵列时,XP上的内存泄漏严重,而Vista或更高版本上的硬盘崩溃严重。您需要更改C代码以将内存用于分配给已知堆的返回输出缓冲区。这需要使用CoTaskMemAlloc()

另一个可能的解决方法是导出一个允许调用者释放缓冲区的函数。在这种情况下,您应该声明参数out IntPtr并使用Marshal.Copy()进行编组,然后使用添加的函数释放缓冲区。

或者使用一种完全不同的方式使用该函数,例如让Compress()仅压缩而不返回数据。客户端代码可使用其他功能来发现所需的缓冲区大小并获取数据副本。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何从函数返回指向数组的指针?

来自分类Dev

如何从函数返回指向结构的指针?

来自分类Dev

如何从静态成员函数调用指向成员函数的指针?

来自分类Dev

如何从静态成员函数调用指向成员函数的指针?

来自分类Dev

如何删除指向动态分配对象的指针数组

来自分类Dev

如何分配指向结构的2D指针数组

来自分类Dev

如何调用函数指针数组中的函数?

来自分类Dev

如何调用返回空指针的函数?

来自分类Dev

如何调用指向从映射中检索的成员函数的指针?

来自分类Dev

如何加快在C ++中返回指向对象的指针的函数?

来自分类Dev

如何从静态函数返回指向const的指针?

来自分类Dev

如何修复我的代码以从函数返回指向结构的指针

来自分类Dev

C ++:如何返回指向非静态成员函数的指针?

来自分类Dev

如何添加指向函数和返回值的指针?

来自分类Dev

如何返回指向char数组中间内容的指针?

来自分类Dev

我如何释放一个指针数组,其中每个指针都指向我在函数内部分配的字符串的地址?

来自分类Dev

如何使用循环初始化指向函数的指针数组

来自分类Dev

如何自动初始化指向函数的指针数组?

来自分类Dev

如何在函数中返回指针数组?

来自分类Dev

返回指向新数组的指针

来自分类Dev

如何为指向指针的指针分配内存?

来自分类Dev

如何修改指针指向的数组

来自分类Dev

如何添加指向数组的指针?

来自分类Dev

如何分配和释放函数指针数组,并使valgrind保持快乐?

来自分类Dev

如何编写给定指向地图的指针,然后返回指向地图中特定元素的指针的函数?

来自分类Dev

如何创建指向函数指针的指针?

来自分类Dev

指向指针数组的指针!如何删除?

来自分类Dev

指向指针数组的指针!如何删除?

来自分类Dev

如何声明指向指针数组的指针

Related 相关文章

  1. 1

    如何从函数返回指向数组的指针?

  2. 2

    如何从函数返回指向结构的指针?

  3. 3

    如何从静态成员函数调用指向成员函数的指针?

  4. 4

    如何从静态成员函数调用指向成员函数的指针?

  5. 5

    如何删除指向动态分配对象的指针数组

  6. 6

    如何分配指向结构的2D指针数组

  7. 7

    如何调用函数指针数组中的函数?

  8. 8

    如何调用返回空指针的函数?

  9. 9

    如何调用指向从映射中检索的成员函数的指针?

  10. 10

    如何加快在C ++中返回指向对象的指针的函数?

  11. 11

    如何从静态函数返回指向const的指针?

  12. 12

    如何修复我的代码以从函数返回指向结构的指针

  13. 13

    C ++:如何返回指向非静态成员函数的指针?

  14. 14

    如何添加指向函数和返回值的指针?

  15. 15

    如何返回指向char数组中间内容的指针?

  16. 16

    我如何释放一个指针数组,其中每个指针都指向我在函数内部分配的字符串的地址?

  17. 17

    如何使用循环初始化指向函数的指针数组

  18. 18

    如何自动初始化指向函数的指针数组?

  19. 19

    如何在函数中返回指针数组?

  20. 20

    返回指向新数组的指针

  21. 21

    如何为指向指针的指针分配内存?

  22. 22

    如何修改指针指向的数组

  23. 23

    如何添加指向数组的指针?

  24. 24

    如何分配和释放函数指针数组,并使valgrind保持快乐?

  25. 25

    如何编写给定指向地图的指针,然后返回指向地图中特定元素的指针的函数?

  26. 26

    如何创建指向函数指针的指针?

  27. 27

    指向指针数组的指针!如何删除?

  28. 28

    指向指针数组的指针!如何删除?

  29. 29

    如何声明指向指针数组的指针

热门标签

归档