2010-09-23 2 views
9

Я хотел бы маршалировать массив int от C++ до C#. У меня есть DLL неуправляемого C++, который содержит:Marshal C++ int array to C#

DLL_EXPORT int* fnwrapper_intarr() 
{ 
    int* test = new int[3]; 

    test[0] = 1; 
    test[1] = 2; 
    test[2] = 3; 

    return test; 
} 

с декларацией в заголовке extern "C" DLL_EXPORT int* fnwrapper_intarr();

Я тогда с помощью PInvoke маршалу его в C#:

[DllImport("wrapper_demo_d.dll")] 
[return: MarshalAs(UnmanagedType.SafeArray)] 
public static extern int[] fnwrapper_intarr(); 

И я использую функцию, как так :

int[] test = fnwrapper_intarr(); 

Однако во время выполнения программы я получаю следующую ошибку: SafeArray cannot be marshaled to this array type because it has either nonzero lower bounds or more than one dimension.

Какой тип массива я должен использовать? Или есть лучший способ сортировки массивов или векторов целых чисел?

+0

Если вы являетесь автором fnwrapper_intarr, есть ли что-либо против возврата safearray (или лучше как параметр)? – Liton

ответ

16
 
[DllImport("wrapper_demo_d.dll")] 
public static extern IntPtr fnwrapper_intarr(); 

IntPtr ptr = fnwrapper_intarr(); 
int[] result = new int[3]; 
Marshal.Copy(ptr, result, 0, 3); 

Вы должны также написать Освободить функцию в неуправляемом Dll, который удаляет указатель, созданный fnwrapper_intarr. Эта функция должна принимать параметр IntPtr как параметр.

 
DLL_EXPORT void fnwrapper_release(int* pArray) 
{ 
    delete[] pArray; 
} 

[DllImport("wrapper_demo_d.dll")] 
public static extern void fnwrapper_release(IntPtr ptr); 

IntPtr ptr = fnwrapper_intarr(); 
... 
fnwrapper_release(ptr); 
+1

+1 Отлично! Это сработало, за исключением того, что я думаю, что это должно быть «Marshal.Copy» не «Marshal :: Copy». – Seth

+2

А что делать, если вы не знаете размер массива на стороне C#? – Gleno