У меня есть c ++ нативный DLL (не CLR), который имеет обратный вызов для приложения C #.
Все обратные вызовы работают, кроме следующего:
C ++:
typedef int (__stdcall *TransmitBinaryMessageCallback)(GUID connectionID, byte data[], int data_size);
вызов :
GUID ClientID = { 0x12345678, 0xabcd, 0xef12, { 0xfe, 0xdc, 0xa9, 0x87, 0x65, 0x43, 0x21, 0x11 } };
byte arrayB[10] = {0x2,0x4,0x6,0x8,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
transmitBINMessage(ClientID,arrayB,10);
C #
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int TransmitBinaryMessageCallback(Guid ClientID,byte [] data,int data_size
public static int FuncTransmitBinaryMessageCallback(Guid ClientID, byte[] data, int data_size)
{
try
{
System.Windows.Forms.MessageBox.Show("transmitBinaryMessageCallback: clientID=" + ClientID.ToString() + Environment.NewLine +
"data=" + data.ToString() + Environment.NewLine +
"data_size=" + data_size.ToString());
}
catch
{
return -1;
}
return 1;
}
Я получаю только первый байт => 0x2
Я пробовал также:
char[] arrayBytes = new char[data_size];
BinaryReader reader = new BinaryReader(new MemoryStream(data));
int i = reader.Read(arrayBytes, 0, data_size);
я = 0 🙁
Что мне не хватает?
Я мог бы изменить в C ++ с byte [] на char * и в C # на строку ->
эта работа. НО я хочу байтовый массив, почему он не работает ?!
Маршаллер не знает, какова длина байтового массива. У него нет способа маршалировать это. Я бы объявил data
быть IntPtr
а затем использовать Marshal.Copy
скопировать из неуправляемой памяти в байтовый массив.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int TransmitBinaryMessageCallback(Guid ClientID, IntPtr dataPtr, int data_size);
А затем внутри реализации обратного вызова
byte[] data = new byte[data_size];
Marshal.Copy(dataPtr, data, 0, data_size);
Я не совсем понял, какие расширения Microsoft поставил поверх C ++, но я не верю, что в настоящее время byte
введите C ++. Я создал новый проект MFC DLL, чтобы посмотреть. Их byte
тип не более чем typedef unsigned char byte;
Попробуйте изменить свою подпись на
typedef int (__stdcall *TransmitBinaryMessageCallback)(GUID connectionID, byte* data, int data_size);