Отправить двойной массив с SendMessage WM_COPYDATA
У меня были проблемы с отправкой двойного массива из одного приложения в другое (оба C#).
Я пытаюсь отформатировать CopyData Struct
как это:
[StructLayout(LayoutKind.Sequential)]
public struct CopyDataStruct
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8)]
public double[] lpData;
}
В Sender Application
Я заполняю структуру так:
double[] a = new double[2] { 1.0, 2.0 };
int size = Marshal.SizeOf(typeof(double)) * a.Count();
CopyDataStruct copyDataStruct;
copyDataStruct.dwData = IntPtr.Zero;
copyDataStruct.lpData = a;
copyDataStruct.cbData = size;
int result = SendMessage(hWnd, WM_COPYDATA, 0, ref copyDataStruct);
В Receiver Application
Я пытаюсь это:
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case (int)WINMESSAGES.WM_COPYDATA:
CopyDataStruct cp = (CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));
break;
}
return IntPtr.Zero;
}
но в cp.lpDat
ценность приходит null
, Я не знаю, если я отправил неправильно или я получил неправильно. Пожалуйста, помогите, спасибо.
1 ответ
Вам нужно использовать родную память. Прохождение C# double[]
как это не будет работать. Это будет сборщик мусора (черт возьми, он даже не размещен в C# - он просто в стеке). Вы можете прикрепить объект небезопасными / фиксированными ключевыми словами или использовать AllocHGlobal
,
Это код, который я скопировал из интернета. Демонстрирует отправляющую часть:
// Marshal the managed struct to a native block of memory.
var myStruct = new double[2] { 1.0, 2.0 };
int myStructSize = Marshal.SizeOf(myStruct);
IntPtr pMyStruct = Marshal.AllocHGlobal(myStructSize);
try
{
Marshal.StructureToPtr(myStruct, pMyStruct, true);
COPYDATASTRUCT cds = new COPYDATASTRUCT();
cds.cbData = myStructSize;
cds.lpData = pMyStruct;
// Send the COPYDATASTRUCT struct through the WM_COPYDATA message to
// the receiving window. (The application must use SendMessage,
// instead of PostMessage to send WM_COPYDATA because the receiving
// application must accept while it is guaranteed to be valid.)
NativeMethod.SendMessage(hTargetWnd, WM_COPYDATA, this.Handle, ref cds);
int result = Marshal.GetLastWin32Error();
if (result != 0)
{
MessageBox.Show(String.Format(
"SendMessage(WM_COPYDATA) failed w/err 0x{0:X}", result));
}
}
finally
{
Marshal.FreeHGlobal(pMyStruct);
}
Снято: http://code.msdn.microsoft.com/windowsdesktop/CSReceiveWMCOPYDATA-dbbc7ed7