简体   繁体   English

在C ++非托管dll和C#托管dll之间发送Byte [] []

[英]Sending Byte[][] inbetween C++ unmanaged dll and C# managed dll

I have an unmanaged C++ dll that exports the following methods: 我有一个非托管的C ++ dll,可导出以下方法:

ERASURE_API  void encode(unsigned char ** inp, unsigned char ** outp,
     unsigned int *block_nums, size_t num_block_nums, size_t sz);

ERASURE_API void decode(unsigned char ** inp, unsigned char ** outp,
     unsigned int * index, size_t sz);

Size of inp and outp can be as large as 10KB, What would be the best performance way to call these methods from C# managed code? inp和outp的大小可以高达10KB,从C#托管代码调用这些方法的最佳性能方法是什么?

EDIT: I did the following implementation, and It works, but is it the most efficient way to do this. 编辑:我做了以下实现,并且有效,但这是最有效的方法。

C++ : C ++:

ERASURE_API  void encode_w(unsigned char * inpbuf,int k, unsigned char * outpbuf,
    int nfecs, unsigned int * block_nums, size_t num_block_nums, size_t sz)
{ 
   unsigned char ** inp= new unsigned char*[k];
    for(i=0;i<k;i++){
        inp[i] = inpbuf+i*sz;
    }

unsigned char ** outp= new unsigned char *[nfecs];
    for(i=0;i<nfecs;i++){
        outp[i] =outpbuf+i*sz;
    }
    encode(inp,outp,block_nums,num_block_nums,sz);
    delete [] inp;
    delete [] outp;
}

C#: C#:

[DllImport("erasure.dll")]
public static extern void encode_w([In] byte[] inpbuf,int k,[Out] byte[] outpbuf,
     int nfecs, uint[] block_nums, int num_block_nums, int sz);

Is C++/CLI an option? 是否可以选择C ++ / CLI? IMO, it's these sorts of complex interop/custom marshaling scenarios for which it was designed. IMO,它是为这类复杂的互操作/自定义封送处理方案而设计的。

Errg that's some awesome Marshalling to be done there. Errg那是在那儿要做的很棒的编组。

I've only ever come across one good article that deals with this sort of thing: 我只见过一篇很好的文章,涉及这种事情:
Marshalling a Variable-Length Array From Unmanaged Code In C# 在C#中从非托管代码整理可变长度数组

Do you have to marshal data between managed and native heap? 您是否需要在托管堆和本机堆之间封送数据? If you move all operation on the buffer to your native DLL you can avoid the cost of data copy between heaps. 如果将缓冲区上的所有操作移至本机DLL,则可以避免在堆之间进行数据复制的开销。

That means you need to allocate the data on the native heap, return it in a ref IntPtr parameter, then hold the buffer's address in IntPtr (.Net equivalent of void*) and pass it around. 这意味着您需要在本机堆上分配数据,将其返回给ref IntPtr参数,然后将缓冲区的地址保存在IntPtr(等效于void *的.Net)中并将其传递。 After you are done with the buffer you can call another function in your native dll to delete the buffer. 使用完缓冲区后,可以在本机dll中调用另一个函数以删除缓冲区。 Use System.Runtime.InteropServices.Marshal.Copy when you have to copy the data to the managed heap (that's what the CLR marshaller called for marshalling built-in types). 当您必须将数据复制到托管堆时,请使用System.Runtime.InteropServices.Marshal.Copy(这是CLR编组器要求编组内置类型的内容)。

Creating COM wrappers of the buffer-operating functions would be a little slower but makes the code more readable. 创建缓冲区操作函数的COM包装器会稍慢一些,但会使代码更具可读性。 However, allocating on the COM heap could be a little slower because managed code can also locking the COM heap. 但是,在COM堆上进行分配可能会稍慢一些,因为托管代码也可以锁定COM堆。

我建议为这些功能创建COM包装器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM