Как я могу написать подпись на C # для обернутого метода C ++, имеющего двойную косвенность в своих аргументах? - PullRequest
0 голосов
/ 15 сентября 2011

Я пишу обертку для DLL.У dll есть метод, подпись которого похожа на следующее:

unsigned long aMethod(char **firstParameter, char **secondParameter))

aMethod возвращает строковые указатели на все параметры.

Я искал в Google учебник, чтобы дать мне представление о том, какнапишите подпись на C #, чтобы фреймворк мог выполнять процесс сортировки.

Как это можно написать?Знаете ли вы о каком-либо учебнике, книге или документации по этому предмету?

Ответы [ 3 ]

0 голосов
/ 15 сентября 2011

Разве вы не можете просто написать это как

ulong aMethod(out IntPtr firstParameter, out IntPtr secondParameter);

Чтобы использовать это:

IntPtr p1;
IntPtr p2;

aMethod(out p1, out p2);

string p1Str = Marshal.PtrToStringAnsi(p1);
string p2Str = Marshal.PtrToStringAnsi(p2);

Я, конечно, предполагаю, что вы не хотите оперировать фактической памятью, возвращаемой этим методом. Если вы хотите оперировать действительными байтами, вы можете вызвать Marshal.ReadByte, передав ему полученный указатель.

Обратите внимание, что если вызываемый метод выделяет память для этих строк перед передачей вам, у вас есть утечка памяти, если вы не можете вызвать что-то в этом API, чтобы освободить память.

Также обратите внимание, что если вы работаете непосредственно с байтами, нет никакой гарантии, что что-то еще в API не вытянет коврик из-под вас.

0 голосов
/ 15 сентября 2011

Я получил ответ:

Подпись должна быть такой:

[DllImport(aDll.dll, CallingConvention = CallingConvention.Cdecl, 
    CharSet = CharSet.Auto)]
static unsafe extern ulong aMethod(ref IntPtr firstParameter, 
    ref IntPtr secondParameter);

Параметры должны быть объявлены как здесь:

IntPtr firstParameter = new IntPtr();
IntPtr secondParameter = new IntPtr();

И вызов выполняется как:

aMethod(ref firstParameter, ref secondParameter);

Маршаллинг и демаршаллинг, относящиеся к строкам, как здесь:

Marshal.PtrToStringAnsi(firstParameter)
Marshal.PtrToStringAnsi(secondParameter)

Очевидно, что это сортировка была выбрана в соответствии с соглашениями API dll.

В конце концов, я не уверен, но все проблемы были в источниках Charset и CallingConvention ...

0 голосов
/ 15 сентября 2011

Не совсем отвечая на ваш вопрос, но один инструмент, который может помочь вам, если у вас есть много методов в .dll, которые вы хотите вызвать из C #, это swig http://www.swig.org.Это позволит вам создать оболочку вокруг .dll из файла интерфейса.Один из способов научиться делать это - изучить, как это делает Swig.

...