在C ++ unmanaged dll和C#managed dll之间发送Byte [] []

时间:2009-11-10 07:53:30

标签: c# c++ windows dll unmanaged

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

4 个答案:

答案 0 :(得分:2)

C ++ / CLI是一个选项吗? IMO,它是针对它设计的各种复杂的互操作/自定义编组方案。

答案 1 :(得分:2)

Errg在那里做了一些很棒的编组。

我只遇到一篇处理此类事情的文章:
Marshalling a Variable-Length Array From Unmanaged Code In C#

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:-2)

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

相关问题