2012-06-29 5 views
0

У меня проблема PInvoking родной функции из C++ ... У меня есть PInvoked все остальные собственные функции без проблем (params были очень простыми преобразованиями). ниже C++ прототип и его использование в C++:Функция PInvoke C++ для использования в C#

DECL_FOOAPIDLL DWORD WINAPI FOO_Command(
VOID *Par, //pointer to the parameter(s) needed by the command 
DWORD Len, //length of Parameter in bytes 
DWORD Id //identification number of the command 
); 

использование:

static DWORD DoSomething(WCHAR *str) 
{ 
DWORD len = (wcslen(str)+1)*sizeof(WCHAR); 
DWORD ret = FOO_Command((VOID *)str,len,FOOAPI_COMMAND_CLOSE); 
return(ret); 
} 

мой C# PInvoke:

[DllImport("FOO.dll")] 
    static public extern uint FOO_Command(IntPtr par, uint len, uint id); 

private void DoSomething() 
{ 

    string text = "this is a test"; 
    IntPtr ptr = Marshal.StringToHGlobalUni(text); 

    uint hr = FOO_Command(ptr,255, FOOAPI_COMMAND_CLOSE); 

    Marshal.FreeHGlobal(ptr); 

} 

1) это правильный способ PInvoke этот API? 2) как я могу получить размер ptr, где у меня есть 255 в качестве парм?

выше действительно работает, но я новичок в PInvoke и «родной» мир ...

Спасибо

+0

Врет о вашей длине строки - это, очевидно, короче чем 127 символов, но в противном случае это правильно, если макрос 'DECL_FOOAPIDLL' определяет соглашение о вызове' __stdcall'. – ildjarn

+0

В чем проблема, с которой вы столкнулись? –

+0

Я не был уверен, могу ли я установить PInvoke C# api лучше, чтобы мне не нужно было маршалировать строку указателю ... Но после некоторого исследования я предполагаю, что это единственный способ увидеть, как нужно будет уничтожить указатель после использования ... Должен ли я использовать Marshal.sizeof (ptr), чтобы получить правильную длину строки? Я попробовал просто (text.length + 1), но только половина строки была получена C++ api .... ??? – devHead

ответ

1
private void DoSomething() 
{ 

    string text = "this is a test"; 
    IntPtr ptr = Marshal.StringToHGlobalUni(text); 

    uint hr = FOO_Command(ptr, (text.Length + 1) * 2, FOOAPI_COMMAND_CLOSE); 

    Marshal.FreeHGlobal(ptr); 

} 
+0

Можете ли вы объяснить * 2? ... – devHead

+1

* 2 должен учитывать тот факт, что единица символов UTF-16 имеет ширину 2 байта. Код C++ использует '* sizeof (WCHAR)' для достижения такого же эффекта. –

+0

жаль, что так долго, спасибо – devHead

Смежные вопросы