2009-11-10 70 views
1

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

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); 
+1

可以将inp和outp指向与重叠相同的数组吗? – 2009-11-10 08:13:22

+0

这可能是一个选项。 – rkatiyar 2009-11-10 08:57:20

回答

2

是C++/CLI的选项?海事组织,它是这种设计它的这种复杂的互操作/自定义编组场景。

+0

我们在这里使用C++/CLI讨论了多少性能问题。我需要一个快速的擦除编码和解码实现,这就是为什么我更愿意选择C++非托管。 – rkatiyar 2009-11-10 08:22:46

+0

对不起,我的意思是:使用C++/CLI进行native/managed之间的互操作。缺点是:你最终得到3个代码库(1个本地C++,1个C++/CLI,1个C#)。 – Brannon 2009-11-10 08:29:36

+0

当然,如果您拥有本机C++库,则可以调整接口以更好地支持P/Invoke。如果是这种情况,请稍微描述一下你的情况,以便有人可以给出一个P/Invoke友好的建议。 – Brannon 2009-11-10 08:31:43

-2

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

+0

我相信这是他想要做的。问题是将char **编组回到C#。 – ParmesanCodice 2009-11-10 08:29:14

+0

他可以将char **表示为单独的接口并提供访问数据的便捷方法 – Alex 2009-11-10 08:35:26

+0

我的意思是用C++创建COM包装,而不是C#。而不是在C#中使用它# – Alex 2009-11-10 09:07:31

1

你有元帅托管和本机堆之间的数据?如果将缓冲区上的所有操作移至本机DLL,则可避免堆之间的数据复制成本。

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

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

+0

感谢您的评论,我一定会尝试一下您的建议。我对.NET和c#很陌生。我不知道IntPtr相当于void *。我以为他们只会举行int refs :( – rkatiyar 2009-11-11 17:02:21