Что происходит с байтовым массивом в C # при передаче в неуправляемый код в структуре?

Я работаю над .NET DLL для доступа к библиотеке C ++, которую мне дали. В библиотеке C ++ есть такая структура:

typedef struct FOO
{
DWORD DataSize;
BYTE  *pData;
}

Я воссоздал его в C # таким образом:

[StructLayout(LayoutKind.Sequential)]
public struct FOO
{
public uint DataSize;
public byte[] pData;
}

Мой импорт из C ++ DLL следующий. Я собираюсь включить заголовок со стороны C ++. Метод в C ++ получает указатель на структуру, которую я передаю, поэтому из того, что я смог собрать, передача ссылки будет работать в этом случае:

// C++ Header
HRESULT CallFoo(FOO * pFoo);

[DllImport("SomeLibrary.DLL", EntryPoint = "CallFoo")]
private static extern uint CallFoo(ref FOO rFoo);

Когда я вхожу в свой код на стороне C ++, я получаю структуру, но значение в pData является адресом памяти. Похоже, что это загрязняет код в библиотеке C ++, но я не могу понять, какой HRESULT он мне возвращает (я задал вопрос владельцу библиотеки C ++ относительно сообщения об ошибке).

Другой подход, который я выбрал, основанный на ответ на этот вопрос, было попробовать передать IntPtr вместо байтового массива. Я изменил структуру:

[StructLayout(LayoutKind.Sequential)]
public struct FOO
{
public uint DataSize;
public IntPtr pData;
}

и назвать это:

FOO fooParm = new Foo();
var ptr = IntPtr.Zero;
byte[] bArr = MethodThatReturnsAByteArray();

ptr = Marshal.AllocHGlobal(bArr.Length);
Marshal.Copy(bArr, 0, ptr, bArr.Length);

fooParm.pData = ptr;
fooParm.DataSize = bArr.Length;

uint i = CallFoo(fooParm);

Это, к сожалению, тоже не работает. Я получаю тот же код ошибки, что и оригинальный подход.

1

Решение

Весь ваш подход не хорош. Существует некоторая информация о компоновке управляемых структур / классов, но лучше ее не использовать. Попробуйте сделать это:

[DllImport("SomeLibrary.DLL", EntryPoint = "CallFoo")]
private static extern uint CallFoo(uint DataSize, IntPtr pData);

Чем больше простых параметров вы передаете туда и обратно, тем лучше будет результат.

1

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

У меня нет библиотеки C ++ передо мной, поэтому сложно ответить на этот вопрос точно, я чувствую, но похоже, что вы получаете указатель, и у библиотеки возникают проблемы с этим. Будет ли возможно использовать Marshal::PtrToStructure чтобы сопоставить это byte[] указатель на правильный struct?

Вот ссылка на конкретный метод, о котором я говорю. Второй пример кода в нижней части (в C ++) может применяться: http://msdn.microsoft.com/en-US/library/4ca6d5z7.aspx

1

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