Получить указатель c ++ для c #

У меня есть C ++ DLL, которая имеет некоторые внешние функции.
и это выглядит так

//C++ Code
void GetData(byte * pData)
{
byte a[] = {3,2,1};
pData = a;
}

и я должен использовать этот код на стороне C # для получения данных:

//C# Code
[DllImport(UnmanagedDLLAddress)]
public static extern void GetData(ref IntPtr pData);

//and use it like
IntPtr pointer = IntPtr.Zero;
GetData(ref pointer);
byte[] data = new byte[3] // <===== think we know size
Marshal.Copy(pointer,data ,0,3);

но всегда «указатель» равен нулю, поэтому Marshal.Copy выдает исключение NULL
где я ошибся?
ти

0

Решение

Во-первых, ваш код C ++ помещает массив в стек. Вам нужно разместить его как-то иначе, для начала документации отсюда: http://msdn.microsoft.com/en-us/library/aa366533%28VS.85%29.aspx

Во-вторых, pData — это «нормальный» аргумент значения, фактически локальная переменная. Вы присваиваете ему значение, затем оно забывается, когда функция возвращается. Вам нужно, чтобы это была ссылка на указатель или указатель на указатель, если вы хотите, чтобы это был «параметр out», возвращающий значение обратно. Если вы хотите скопировать содержимое массива в буфер, на который указывает pData, вам нужно использовать memcpy функция от #include <cstring>,

5

Другие решения

На самом деле, как сказал Хайд, используйте pData в качестве параметра «out».
Поскольку это явно ссылочный тип, а не тип значения, вызываемый метод должен позаботиться о распределении памяти. Я использовал «ref» только для типов значений, таких как целые числа — например, получение длины массива из неуправляемого метода.

Этот способ хорошо работает для меня, кроме того, я использую соглашение о вызовах «cdecl».

IntPtr aNewIntArray;
uint aNewIntArrayCount = 0;

NativeMethods.getEntityFieldIntArray(out aNewIntArray, ref aNewIntArrayCount);

int[] aNewIntArrayResult = new int[aNewIntArrayCount];
Marshal.Copy(aNewIntArray, aNewIntArrayResult, 0, (int)aNewIntArrayCount);

объявление метода:

[DllImport(SettingsManager.PathToDLL, EntryPoint = "getEntityFieldIntArray", CallingConvention = CallingConvention.Cdecl)]
public static extern ErrorCode getEntityFieldIntArray(out IntPtr aNewIntArray, ref UInt32 aNewIntArrayCount);
3

По вопросам рекламы [email protected]