C # SendMessage для C ++ WinProc - PullRequest
       29

C # SendMessage для C ++ WinProc

4 голосов
/ 16 апреля 2010

Мне нужно отправить строку из C # в C ++ WindowProc. Есть несколько связанных вопросов по SO, связанных с этим, но ни один из ответов не сработал для меня. Вот ситуация:

PInvoke:
[DllImport("user32", CharSet = CharSet.Auto)]
public extern static int SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, string lParam);

C#:
string lparam = "abc";
NativeMethods.User32.SendMessage(handle, ConnectMsg, IntPtr.Zero, lparam);

C++:
API LRESULT CALLBACK HookProc (int code, WPARAM wParam, LPARAM lParam)
{       
    if (code >= 0)
    {
        CWPSTRUCT* cwp = (CWPSTRUCT*)lParam;
                ...
        (LPWSTR)cwp->lParam   <-- BadPtr
                ...
    }

    return ::CallNextHookEx(0, code, wParam, lParam);
}

Я попробовал несколько разных вещей, выделив строку как LPStr, LPWStr, также попытался создать IntPtr из неуправляемой памяти и записать в него с помощью Marshal.WriteByte.

Указатель - это правильная ячейка памяти на стороне C ++, но данных там нет. Чего мне не хватает?

Ответы [ 2 ]

2 голосов
/ 16 апреля 2010

Для параметров C ++ LPWSTR или LPSTR вам необходимо использовать C # StringBuilder в вашем DllImport.

Для параметров C ++ LPCWSTR или LPCSTR вам необходимо использовать C # string в вашем DllImport.

1 голос
/ 16 апреля 2010

Убедитесь, что ваш вызов SendMessage происходит ожидаемым, синхронным образом и что ваш класс NativeMethods отображает правильный вызов Win32 (Send vs. PostMessage.) на стороне C ++ вы оставили область действия вашего метода C #, и все локальные переменные, созданные в стеке, исчезли, что привело к неверному указателю.

Вопросы стека и кучи для вызовов между потоками: потоки имеют свои собственные стеки, но разделяют кучу. Перемещенные в стеке переменные в одном потоке не будут видны в другом. Тип строки - странная утка в .NET. Это объектный, ссылочный тип, но созданный для того, чтобы выглядеть и чувствовать себя как тип значения в коде. Так что, возможно, передача указателя на данные, выделенные в куче, должна работать. Вот тут и появляется StringBuilder как тип ссылки, выделенный в куче.

...