2015-07-07 3 views
0

Я разрабатываю программу, которая использует файл драйвера dll. Я успешно связывал DLL в мой код, но есть проблема с одним методомC++/C# Преобразование типа совместимости

Dll функции:

word NdEnumDevices(const char* const ** devs); 

Я связал его с C#, как этот

[DllImport("NeurobitDrv.dll")] 
    public static extern ushort NdEnumDevices(ref string[] devs); 

Как я не имеют большой опыт работы с C++. Я действительно не понимаю, что означает const char* const ** devs. Я знаю, что этот аргумент принимает массив строк, но я только получить один элемент, где должен быть 3

И выкидывает нарушение прав доступа Exception

Может кто-нибудь сказать мне, какой тип я должен использовать в C#? ?


Я работал вокруг него, просто жёстко массив строк с именами устройств, и она работает просто отлично: D

+0

Я бы предположил, что это должна быть строка ',' '. Кто-то еще может объяснить 'const'-ness или ссылку на статью. –

+0

Nope. Я уже пробовал это –

+0

'const char * const **' означает указатель на указатель на константный указатель на постоянный символ. 'const char *' используется для c-строк. Вероятно, вам не хватает уровня косвенности (т. Е. '**' part) – OMGtechy

ответ

0

const char* const ** devs, вероятно, такой же, как const char* const *devs[] который будет

pointer to 
    an array of 
    constant pointers to 
     constant characters. 

Это скорее всего, будет ref (хотя я не слишком уверен в этом). A ref в массив строк можно скомпилировать как указатель на массив строк.

Как указано в вопросе this, вы должны быть в безопасности, чтобы использовать const char*.

Я думаю, что вам не хватало длину массива. Функция должна быть объявлена ​​как

word NdEnumDevices(const char* devs[], unsigned int length); 
// C# 
[DllImport("NeurobitDrv.dll")] 
private static extern ushort NdEnumDevices(string[] devs, UInt32 length); 

public static ushort NdEnumDevices(string[] devs) { 
    NdEnumDevices(devs, devs.Length); // Delegate for length 
} 
+0

Так что мой код должен работать нормально. Любые идеи, почему это не так? –

+0

@CezaryKarabela Вероятно, это связано с тем, что строка .NET и char * реализованы радикально иными? Либо используйте строку .NET на стороне C++, либо используйте небезопасный код C# и используйте char * на стороне C#. – KABoissonneault

+1

Если бы это был только указатель на строку с нулевым завершением, ваш код будет работать. Marshaller создает System.String из первого найденного указателя char *. Но для char ** нет маршаллинга по умолчанию. Поэтому вы можете попытаться настроить его как «ref IntPtr», а затем прочитать строки с помощью Marshal.PtrToStringAnsi Но для этого вам нужно знать, сколько строк в массиве .. они заканчиваются двумя значениями 0? –