В данной статье мы рассмотрим проблему передачи структуры из C# в Delphi через WM_COPYDATA и предложим решение для ее решения.
Описание проблемы
Разработчик столкнулся с проблемой передачи структуры из C# в Delphi через WM_COPYDATA. Несмотря на то, что он следовал формату из https://www.pinvoke.net/default.aspx/Structures.COPYDATASTRUCT для копирования данных структуры, на стороне Delphi не получалось принять сообщение. Разработчик подозревает, что проблема может быть связана с неправильным кодированием структуры.
Решение проблемы
Для решения проблемы мы предлагаем следующим образом изменить код в C#:
Убедитесь, что в структуре COPYDATASTRUCT присутствует атрибут [StructLayout(LayoutKind.Sequential)].
Измените определение функции SendMessage на SendMessageCopyData, как показано ниже:
[DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage", SetLastError = false)]
public static extern int SendMessageCopyData(IntPtr hWnd, int uMsg, UIntPtr wParam, ref COPYDATASTRUCT lParam);
Добавьте метод IntPtrAlloc<T>, который выделяет память под структуру и копирует ее в выделенный участок памяти:
Измените метод SendFingerPrintResult следующим образом:
public void SendFingerPrintResult(string msg)
{
// Получаем окно для отправки структуры
IntPtr receiverHandle = GetWindow();
if (receiverHandle == IntPtr.Zero) return;
// Получаем структуру
ReturnStruct ret = GetReturnStruct();
IntPtr ptr = IntPtrAlloc(ret);
try
{
var cds = new COPYDATASTRUCT
{
dwData = IntPtr.Zero,
cbData = Marshal.SizeOf(ret),
lpData = ptr
};
IntPtr iPtr = IntPtrAlloc(cds);
try
{
SendMessageCopyData(receiverHandle, WM_COPYDATA, senderID, iPtr);
}
finally
{
IntPtrFree(ref iPtr);
}
}
finally
{
IntPtrFree(ref ptr);
}
}
Измените структуру ReturnStruct следующим образом:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct ReturnStruct
{
public int i;
public byte card_len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
public string card;
public byte name_len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string name;
public byte responsecode_len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
public string responsecode;
public byte responsetext_len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string responsetext;
public byte approval_len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)]
public string approval;
public byte tranid_len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
public string tranid;
public byte reference_len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string reference;
public double d;
public byte transactionType_len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)]
public string transactionType;
public byte creditCardType_len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
public string creditCardType;
public int EMVContact;
public byte applicationName_len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
public string applicationName;
public byte applicationIdentifier_len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)]
public string applicationIdentifier;
public byte reserved_len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
public string reserved;
}
Добавьте метод GetReturnStruct, который заполняет структуру ReturnStruct данными:
public ReturnStruct GetReturnStruct()
{
var ret = new ReturnStruct();
ret.i = ...;
ret.card = ...;
ret.card_len = (byte)Math.Min(System.Text.Encoding.Default.GetByteCount(ret.card), 50);
ret.name = ...;
ret.name_len = (byte)Math.Min(System.Text.Encoding.Default.GetByteCount(ret.name), 100);
// Заполните остальные поля структуры аналогичным образом
return ret;
}
После внесения этих изменений, сообщение с структурой должно быть принято на стороне Delphi без проблем.
В данной статье рассматривается проблема передачи структуры из C# в Delphi через `WM_COPYDATA` и предлагается решение для ее решения.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.