1

私はc++相互運用機能を備えたc#アプリで共有メモリを使用しています。現在、構造体をポインタにマーシャリングし、メッセージをブロードキャストしています。ブロードキャストしているプログラムは、デバッグメッセージで正しく開きますが、構造内で使用していたデータを表示/取り込みません。

ありがとう!

私が話そうとしているアプリはc++で書かれていて、c#でコーディングしています。私はすべてのDLLImportsを正しく使用しており(私は思う)、コンパイルしてエラーなしで実行します。

using System.Runtime.InteropServices;

[DllImport("user32", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
public static extern uint RegisterWindowMessageW([In]string lpString);

[DllImport("user32", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public static extern uint RegisterWindowMessageA([In]string lpString);

[DllImport("kernel32", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto)]
public static extern IntPtr OpenFileMapping(FileMapAccessRights dwDesiredAccess, int bInheritHandle, [In]String lpName);

[DllImport("kernel32", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto)]
public static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, FileMapAccessRights dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, UIntPtr dwNumberOfBytesToMap);

[DllImport("kernel32", CallingConvention = CallingConvention.StdCall)]
public static extern int UnmapViewOfFile(IntPtr lpBaseAddress);

[DllImport("kernel32", CallingConvention = CallingConvention.StdCall)]
public static extern int CloseHandle(IntPtr hObject);

[DllImport("user32.dll")]
public static extern IntPtr PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);

uint WM_ZOOM_XYZ = RegisterWindowMessageA("WM_ZOOM_XYZ");

int i = Broadcast_Zoom_Message(10000, 10000, 0, WM_ZOOM_XYZ);

public int Broadcast_Zoom_Message(double dbX, double dbY, double dbZ, uint uMessage) 
{
    string smSharedMemory = "COORDINATES";

    IntPtr hMem = OpenFileMapping(FileMapAccessRights.Write, FALSE, smSharedMemory);

    if (IntPtr.Zero == hMem)
    {
        return 0;
    }

    IntPtr pvHead = MapViewOfFile(hMem, FileMapAccessRights.Write, 0, 0, UIntPtr.Zero);


    if (IntPtr.Zero == pvHead)
    {
        CloseHandle(hMem);
        MessageBox.Show(
            "Unable to view " + smSharedMemory, 
            "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
        return 0;
    }

    CoordinatesStruct structCoords = new CoordinatesStruct();


    Marshal.PtrToStructure(pvHead, structCoords);

    int bVersionOk = FALSE;

    if (1 == structCoords.uMajorVersion)
    {
        if (WM_ZOOM_XYZ == uMessage)
        {
            structCoords.dbDesiredX = dbX;
            structCoords.dbDesiredY = dbY;
            structCoords.dbDesiredZ = dbZ;
        }
        bVersionOk = TRUE;
    }
    else
    {
        MessageBox.Show(
            "Unrecognized shared memory: " +
            structCoords.uMajorVersion.ToString() + "." + structCoords.uMinorVersion.ToString());
    }
    if (IntPtr.Zero != hMem)
    {
        CloseHandle(hMem);
    }
    UnmapViewOfFile(pvHead);

    IntPtr HWND_BROADCAST = (IntPtr)0xffff;

    if (bVersionOk == TRUE)
    {
        PostMessage(HWND_BROADCAST, uMessage, 0, 0);
        return 1;
    }
    else
        return 0;
}
4

1 に答える 1

1

あなたの意図は、変更structCoordsをマップされたファイルに戻すことだったと思います。使用するMarshal.PtrToStructure()と、アンマネージメモリのコンテンツのコピーを受け取ります。受信したオブジェクトの変更は、アンマネージメモリには反映されません。データの処理が完了したら、を使用して変更をメモリに戻す必要がありますMarshal.StructureToPtr

これが私がそうあるべきだと思うものです:

if (1 == structCoords.uMajorVersion)
{
    if (WM_ZOOM_XYZ == uMessage)
    {
        structCoords.dbDesiredX = dbX;
        structCoords.dbDesiredY = dbY;
        structCoords.dbDesiredZ = dbZ;
    }
    bVersionOk = TRUE;
    Marshal.StructureToPtr(structCoords , pvHead, false); // <-- this is what you (I) forgot!
}
于 2012-05-24T04:14:56.803 に答える