在C和x2B之间发送字节[]+;非托管dll和C#托管dll 我有一个非托管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);

在C和x2B之间发送字节[]+;非托管dll和C#托管dll 我有一个非托管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);,c#,c++,windows,dll,unmanaged,C#,C++,Windows,Dll,Unmanaged,inp和outp的大小可以高达10KB,从C#托管代码调用这些方法的最佳性能方式是什么 编辑:我做了下面的实现,它是有效的,但这是最有效的方法 C++: C++/CLI是一个选项吗?依我看,它就是为这些复杂的互操作/自定义封送方案而设计的。我建议为这些函数创建COM包装器。呃,这是一个非常棒的封送方案 我只见过一篇关于这类事情的好文章: 您必须在托管堆和本机堆之间封送数据吗?如果将缓冲区上的所有操作移动到本机DLL,则可以避免在堆之间复制数据的成本 这意味着您需要在本机堆上分配数据,在ref I

inp和outp的大小可以高达10KB,从C#托管代码调用这些方法的最佳性能方式是什么

编辑:我做了下面的实现,它是有效的,但这是最有效的方法

C++:


C++/CLI是一个选项吗?依我看,它就是为这些复杂的互操作/自定义封送方案而设计的。

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

呃,这是一个非常棒的封送方案

我只见过一篇关于这类事情的好文章:

您必须在托管堆和本机堆之间封送数据吗?如果将缓冲区上的所有操作移动到本机DLL,则可以避免在堆之间复制数据的成本

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


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

inp和OUP是否可以指向重叠中的相同数组?这可能是一个选项。我们在这里讨论的C++/CLI的性能缺陷有多大。我需要一个快速的擦除编码和解码实现,这就是为什么我更喜欢选择C++非托管的原因。抱歉,我的意思是:在本地/托管之间使用互操作的C++/CLI。缺点是:最终有3个代码库(1个本地C++,1个C++/CLI,1个C++)。当然,如果拥有本地C++库,您可以定制接口以更好地支持P/UnjKE。如果是这样的话,请再多描述一下您的场景,以便有人能给出一个P/Invoke友好的建议。我添加了我为这个问题所做的代码,我希望现在场景更加清晰。我相信这就是他试图做的。问题是将char **编组到C语言中,他可以将char **表示为一个单独的接口,并提供了方便的方法来访问C++中的COM包装器,而不是C语言。而不是在C#@Alex中使用它,现在我明白你在说什么了。我以前在VB6.0中做过这件事。我想那些日子已经过去了:)谢谢你的评论,我一定会尝试你的建议。我对.NET和c#很陌生。我不知道IntPtr等同于void*。我以为他们只会持有int REF:(
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;
}
[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);