LPCWSTR w c#

0

Witam ,
mam problem z przesłaniem struktury za pomocą WM_COPYDATA z c++ do c# właśnie z powodu typu LPCWSTR i hdc . Rozumem ze żeby przesłać taka strukturę muszę ja stworzyć w c# .
pytanie 1 jakich typów użyć ? jak wypełnić taka strukturę ?

tak wygląda która chce przesłać w w c++

struct Struktura
{
HDC hdc;
int X;
int Y;
LPCWSTR text;

};

w c# próbowałem ustawic text jako IntPtr i wypełnić w ten sposób ale coś nie działa ;)

protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case Win32.WM_COPYDATA:
struktura sStruktura;
Win32.CopyDataStruct st = (Win32.CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(Win32.CopyDataStruct));

                sStruktura = (struktura)Marshal.PtrToStructure(st.lpData, typeof(struktura));
                string tx = Marshal.PtrToStringUni(struktura.Text);

              
                textBox1.Text += tx;  // wyświetla same krzaki albo nic  czasem się zawiesza generalnie masaka
                break;
            default:
                base.WndProc(ref m);
                break;
        }
    }

Z góry dziękuję za odpowiedź

0

Nie pokazałaś jak wygląda twoja struktura w C#. Generalnie użyj atrybutów do jej oznakowania, aby była zgodna z kodem C++. LayoutKind oraz MarshalAs to coś co może ci pomóc. Zerknij też na http://pinvoke.net, być może już ktoś ją tam dodał.

Co do typów to użyłbym IntPtr w obu przypadkach.

0

dzięki za pomoc .Po przeczytaniu twojego postu stworzyłem cos takiego

[StructLayout(LayoutKind.Auto, CharSet=CharSet.Unicode)]
struct Struktura{
IntPtr hdc;
public int X;
public int Y;
[MarshalAs(UnmanagedType.LPWStr)] public string text;
}

niestety w czasie wykonania
struktura = (Struktura)Marshal.PtrToStructure(st.lpData, typeof(Struktura));

wyskakuje błąd

An unhandled exception of type 'System.ExecutionEngineException' occurred in mscorlib.dll

przy ustawieniu tekstu na IntPtr pojawia się
Additional information: Nie można zorganizować pola 'text' typu 'Struktura': Nieprawidłowa kombinacja typów zarządzanych/niezarządzanych (wartości Int/UInt muszą łączyć się z elementem SysInt lub SysUInt).

możne ja złe przesyłam ?

COPYDATASTRUCT cds;
::ZeroMemory(&cds, sizeof(COPYDATASTRUCT));
cds.dwData = Chat ;
cds.lpData = (PVOID)&sStruktura;
cds.cbData = sizeof(Struktura) ;

::SendMessage(hWnd, WM_COPYDATA, (WPARAM)::GetDesktopWindow(), (LPARAM)&cds);
0

Możesz pokazać jak wygląda COPYDATASTRUCT?

0

[StructLayout(LayoutKind.Sequential)]
public struct CopyDataStruct
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;

    }
0

No to trochę chyba odstaje od tego co chcesz przesłać z C++. Z tego co rozumiem wysyłasz takie coś:

struct Struktura
{
        HDC hdc;
        int X;
        int Y;
        LPCWSTR text;
};

Zatem nie bardzo ma się to do tego co pokazałeś w poście powyżej. Czy coś namieszało nam się już?

0

no tak i ta moja Struktura(wskaźnik do niej ) znajduje się w strukturze COPYDATASTRUCT cds odbieranej przez WM_COPYDATA w c#
....
cds.lpData = (PVOID)&sStruktura;
cds.cbData = sizeof(Struktura);

0

Dobra, niestety tak na sucho/bez kodu to trudno coś wymyślić.

Moje rady:

  1. Spróbuj z LayoutKind.Sequential (bardziej używane)
  2. Sprawdź rozmiar struktur w kodzie C# i w C++. Muszą być takie same.
  3. Spróbuj z innym atrybutem dla stringa (UnmanagedType.LPWStr - może jednak Ansi zamiast tego?)
  4. Debuguj i sprawdź czy po rzutowaniu CopyDataStruct w ogóle ma sensowne dane w sobie (rozmiar powinien się zgadzać z tym co wysłałeś w C++)
  5. nie wiem co jeszcze..:(

1 użytkowników online, w tym zalogowanych: 0, gości: 1