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

发布于 2024-08-10 20:51:56 字数 1129 浏览 7 评论 0原文

我有一个非托管 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);

inp 和 outp 的大小可以大到 10KB,从 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#:

[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);

I have an unmanaged C++ dll that exports the following methods:

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?

EDIT: I did the following implementation, and It works, but is it the most efficient way to do this.

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#:

[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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

望喜 2024-08-17 20:51:56

C++/CLI 是一种选择吗? IMO,它就是为这些复杂的互操作/自定义编组场景而设计的。

Is C++/CLI an option? IMO, it's these sorts of complex interop/custom marshaling scenarios for which it was designed.

君勿笑 2024-08-17 20:51:56

呃,这是一些很棒的编组工作。

我只见过一篇处理这类事情的文章:
编组C# 中非托管代码的可变长度数组

Errg that's some awesome Marshalling to be done there.

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#

月亮坠入山谷 2024-08-17 20:51:56

您是否必须在托管堆和本机堆之间编组数据?如果将缓冲区上的所有操作移至本机 DLL,则可以避免堆之间数据复制的成本。

这意味着您需要在本机堆上分配数据,在 ref IntPtr 参数中返回它,然后在 IntPtr 中保存缓冲区的地址(.Net 相当于 void*)并将其传递。使用完缓冲区后,您可以调用本机 dll 中的另一个函数来删除缓冲区。当必须将数据复制到托管堆(这就是 CLR 编组器对编组内置类型的调用)时,请使用 System.Runtime.InteropServices.Marshal.Copy。

创建缓冲区操作函数的 COM 包装器会稍微慢一些,但会使代码更具可读性。但是,在 COM 堆上分配可能会慢一些,因为托管代码也可以锁定 COM 堆。

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.

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. After you are done with the buffer you can call another function in your native dll to delete the buffer. 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).

Creating COM wrappers of the buffer-operating functions would be a little slower but makes the code more readable. However, allocating on the COM heap could be a little slower because managed code can also locking the COM heap.

与风相奔跑 2024-08-17 20:51:56

我建议为这些函数创建 COM 包装器。

I would recommend creating COM wrapper for these functions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文