나는 그것을 가지고있다.
간단한 접근 방식은 구조체를 단일 문자열로 serialize하고 문자열을 전송하는 것입니다. swhistlesoft 블로그가 유용했습니다 http://www.swhistlesoft.com/blog/2011/11/19/1636-wm_copydata-with-net-and-c
간단한 메시지를 제공하기에 충분할 수 있습니다. 구조체는 필요한 경우 다른 끝에서 다시 구성 할 수 있습니다.
문자열의 수가 많은 구조체를 그대로 정렬해야하는 경우 고정 크기 여야합니다. 이것이 내가 얻지 못한 주요한 부분입니다.
MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 9)
기본적으로 우리의 경우에 TCHAR szTest있는 C++ 크기와 일치하는 크기를 설정 [9];
a.내가로서해야 할 일을했을 C에 C#을 ++ (/ CLI)에서 WM_COPYDATA를 통해 인터넷 구조체는 다음과 같습니다
COPYDATASTRUCT cd = new COPYDATASTRUCT();
cd.dwData = 2;
cd.cbData = parameters.Length + 1;
cd.lpData = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(parameters);
IntPtr cdBuffer = IntPtrAlloc(cd);
messageReceived = ((int)SendMessage(targetProcess.MainWindowHandle, WM_COPYDATA, IntPtr.Zero, cdBuffer)) != 0;
C에서 문자열을받을 ++ :
else if(pCDS->dwData == 2)
{
//copydata message
CString csMessage = (LPCTSTR)pCDS->lpData;
OutputDebugString("Copydata message received: " + csMessage);
}
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
static extern bool SetForegroundWindow(IntPtr hWnd);
public static uint WM_COPYDATA = 74;
//from swhistlesoft
public static IntPtr IntPtrAlloc<T>(T param)
{
IntPtr retval = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(param));
System.Runtime.InteropServices.Marshal.StructureToPtr(param, retval, false);
return (retval);
}
//from swhistlesoft
public static void IntPtrFree(IntPtr preAllocated)
{
if (IntPtr.Zero == preAllocated) throw (new Exception("Go Home"));
System.Runtime.InteropServices.Marshal.FreeHGlobal(preAllocated);
preAllocated = IntPtr.Zero;
}
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
public uint dwData;
public int cbData;
public IntPtr lpData;
}
/// <summary>
/// Dot net version of AppInfo structure. Any changes to the structure needs reflecting here.
/// struct must be a fixed size for marshalling to work, hence the SizeConst entries
/// </summary>
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1)]
struct AppInfoDotNet
{
public int nVersion;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 9)]
public string test;
};
문자열을 보내려면
보낼 구조체 :
AppInfoDotNet appInfo = new AppInfoDotNet();
appInfo.test = "a test";
COPYDATASTRUCT cds3;
cds3.dwData = 1;
cds3.cbData = System.Runtime.InteropServices.Marshal.SizeOf(appInfo);
IntPtr structPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(System.Runtime.InteropServices.Marshal.SizeOf(appInfo));
System.Runtime.InteropServices.Marshal.StructureToPtr(appInfo, structPtr, false);
cds3.lpData = structPtr;
IntPtr iPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(System.Runtime.InteropServices.Marshal.SizeOf(cds3));
System.Runtime.InteropServices.Marshal.StructureToPtr(cds3, iPtr, false);
messageReceived = ((int)SendMessage(targetProcess.MainWindowHandle, WM_COPYDATA, IntPtr.Zero, iPtr)) != 0;
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(iPtr);
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(structPtr);
C++로 ceive 구조체는 :
LRESULT CMainFrame::OnCopyData(WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = FALSE;
COPYDATASTRUCT *pCDS = (COPYDATASTRUCT*)lParam;
//Matching message type for struct
if(pCDS->dwData == 1)
{
AppInfo *pAppInfo = (AppInfo*)pCDS->lpData
lResult = true;
}
이 데모 코드이며, 필요 예외 처리 등 등 ...
감사, 스타일 측면에서 작동 있습니다. WM_COPYDATA에서 사용자 지정 구조체를 마샬링하기 위해이 사이트에서 찾은 유일한 작업입니다. –