ちょっと備忘録6

COPYDATASTRUCTを使ったC#C++への通信

送信側(CS)

private void SendTextMessage(string t)
{
    IntPtr hwnd = FindWindow(null, "SendMessageSampleCPP");
    if (hwnd == IntPtr.Zero)
        return;

    IntPtr buf_ptr = IntPtr.Zero;
    IntPtr cds_ptr = IntPtr.Zero;
    try
    {
        var buf = System.Text.Encoding.GetEncoding("shift_jis").GetBytes(t);
        buf_ptr = Marshal.AllocHGlobal(buf.Length);
        Marshal.Copy(buf, 0, buf_ptr, buf.Length);

        var cds = new COPYDATASTRUCT();
        cds.dwData = this.Handle;
        cds.cbData = (uint)buf.Length;
        cds.lpData = buf_ptr;

        cds_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(cds));
        Marshal.StructureToPtr(cds, cds_ptr, false);

        SendMessage(hwnd, WM_COPYDATA, IntPtr.Zero, cds_ptr);
    }
    finally
    {
        var free = new Action<IntPtr>(p => { if (p != IntPtr.Zero) Marshal.FreeHGlobal(p); });
        free(cds_ptr);
        free(buf_ptr);
    }

}

受信側(C++

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COPYDATA:
        {
            auto cds = (COPYDATASTRUCT *)lParam;
            char buf[MAX_PATH] = {};
            memcpy(buf, cds->lpData, cds->cbData);

            int i = 0;
        }
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}