Отправка строки C # в качестве аргумента неуправляемой функции C ++ DLL - PullRequest
2 голосов
/ 07 июня 2011

Я хочу отправить свою строку C # в функцию C ++ DLL. Я преуспел, оба с StringBuilder:

[C#]
public static extern int installHook(StringBuilder directory);
StringBuilder myText = new StringBuilder(512);
myfunc(myText);

[C++]
int OPENGLHOOK_API myfunc(char* directory)
{
    ::MessageBoxA(NULL,directory,"test123",0);
}

и с простой строкой и wchar:

[C#]
public static extern int installHook(string directory);
myfunc("myText");

[C++]
int OPENGLHOOK_API installHook(wchar* directory)
{
    wstring s = directory;
    const wchar_t* wstr = s.c_str();
    size_t wlen = wcslen(wstr) + 1;
    char newchar[100];
    size_t convertedChars = 0;
    wcstombs_s(&convertedChars, newchar, wlen, wstr, _TRUNCATE);

    ::MessageBoxA(NULL,newchar,"test123",0);
}

как уже упоминалось в другом потоке на StackOverflow. Проблема в том, что каждый раз, когда я делаю это, я получаю сообщение об ошибке, потому что сигнатуры функций не совпадают:

Помощник по управляемой отладке «PInvokeStackImbalance» обнаружил проблему в «C: \ Users \ Dave \ Documents \ Visual Studio 2010 \ Projects \ OpenGLInjector \ Loader \ bin \ Release \ Loader.vshost.exe». Дополнительная информация: вызов функции PInvoke 'Loader! Loader.Form1 :: myfunc' нарушил баланс стека. Это вероятно потому, что управляемая подпись PInvoke не совпадает с неуправляемой целевой подписью. Убедитесь, что соглашение о вызовах и параметры подписи PInvoke соответствуют целевой неуправляемой подписи.

Есть идеи, как мне решить мою проблему / что делать отсюда?

Ответы [ 2 ]

3 голосов
/ 07 июня 2011

Я считаю, что проблема заключается в соглашении о вызовах по умолчанию между двумя языками. C # это __stdcall, а c ++ это __cdecl, я считаю. Попробуйте явно указать __stdcall в сигнатурах ваших методов C ++ и посмотрите, не устранит ли это ошибку.

C ++:

int OPENGLHOOK_API __stdcall installHook(wchar* directory)

C #:

[DllImport( "yourdll.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode )]
static extern int installHook(string directory);
0 голосов
/ 07 июня 2011

Вам необходимо явно описать соглашение о неуправляемых вызовах для 32-битной системы, и, кроме того, вам нужно будет явно описать тип неуправляемой строки - ASCII, UTF16 и т. Д.

...