Выделение структуры C в C # - PullRequest
5 голосов
/ 24 августа 2010

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

typedef struct 
{
    char* name;
    BT_ADDR address;
} DeviceList;

extern "C" _declspec(dllexport)DeviceList* PerformQuery();

Структура BT_ADDR аналогична структуре, определенной в wsbth2.h в Win CE SDK. PerformQuery возвращает указатель на массив DeviceList.

В моей программе на C # я выполняю следующую декларацию pinvoke следующим образом

[StructLayout(LayoutKind.Sequential)]
struct DeviceList
{
    public string name;
    public ulong address;
}

[DllImport("BT_Conn.dll")]
public extern static DeviceList[] PerformQuery();

После запуска программы на C # возвращается NotSupportedException. Не могли бы вы посоветовать мне, что не так с моей сортировкой?

1 Ответ

2 голосов
/ 24 августа 2010

Одна проблема заключается в том, что маршаллер не может определить, сколько элементов находится в возвращаемом массиве, что означает, что он не может его маршалировать.

Есть ли у API PerformQuery () какой-то другой способ определениядлина массива?

Если он только когда-либо возвращает 1 элемент, вы можете заставить его вернуть IntPtr, а затем использовать Marshal.PtrToStructure (), как описано здесь:

p/ вызывать функцию C, которая возвращает указатель на структуру

Обновление:

Вы можете использовать такой интерфейс C, например, одну функцию, которая возвращает количество элементов, и одну, которая заполняетпредварительно выделенный массив с элементами.

extern "C" _declspec(dllexport) int GetQueryNumItems(); 
extern "C" _declspec(dllexport) void GetQueryItems(DeviceList* items); 

Тогда определение C # будет выглядеть так:

[DllImport("BT_Conn.dll")]  
public extern static int GetQueryNumItems();
[DllImport("BT_Conn.dll")]  
public extern static void GetQueryItems([In, Out] DeviceList[] items);

И вы бы назвали это в C # следующим образом:

int numItems = GetQueryNumItems();
DeviceList[] items = new DeviceList[numItems];
GetQueryItems(items);

При взаимодействии C # и C ++ мне обычно легче создавать библиотеку классов C ++ / CLI, которая предоставляет управляемый интерфейс для переноса кода C в смешанную DLL.Однако эта опция может быть недоступна, если вы работаете на CE.

...