Отправка байта [] [] между C ++ неуправляемой dll и C # управляемой dll - PullRequest
1 голос
/ 10 ноября 2009

У меня есть неуправляемая DLL C ++, которая экспортирует следующие методы:

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

Размер входных и выходных файлов может достигать 10 КБ. Каков наилучший способ вызова этих методов из управляемого кода 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 ]

2 голосов
/ 10 ноября 2009

Ээээ ... это потрясающий маршаллинг, который нужно там сделать.

Я только когда-либо сталкивался с одной хорошей статьей, которая касается такого рода вещей:
Распределение массива переменной длины из неуправляемого кода в C #

2 голосов
/ 10 ноября 2009

Является ли C ++ / CLI опцией? ИМО, это именно такие сложные сценарии взаимодействия / пользовательского маршалинга, для которых он был разработан.

1 голос
/ 10 ноября 2009

Нужно ли маршалировать данные между управляемой и собственной кучей? Если вы перенесете все операции с буфером в свою собственную DLL, вы сможете избежать затрат на копирование данных между кучами.

Это означает, что вам нужно выделить данные в собственной куче, вернуть их в параметре ref IntPtr, затем сохранить адрес буфера в IntPtr (.Net-эквивалент void *) и передать его. После того, как вы закончили работу с буфером, вы можете вызвать другую функцию в вашем родном dll, чтобы удалить буфер. Используйте System.Runtime.InteropServices.Marshal.Copy, когда необходимо скопировать данные в управляемую кучу (это то, что маршаллер CLR вызвал для маршалинга встроенных типов).

Создание COM-обёрток для функций, работающих с буфером, будет немного медленнее, но сделает код более читабельным. Однако выделение в куче COM может быть немного медленнее, поскольку управляемый код также может заблокировать кучу COM.

0 голосов
/ 10 ноября 2009

Я бы порекомендовал создать оболочку COM для этих функций.

...