Интерфейс из C DLL в .NET - PullRequest
       34

Интерфейс из C DLL в .NET

3 голосов
/ 30 января 2009

У меня есть устаревшая DLL, написанная на C, которую я хотел бы вызвать из приложения C # .NET. Проблема в том, что интерфейс DLL для C DLL довольно сложен. Это примерно так:

__declspec(dllexport) void __stdcall ProcessChunk(
    void *p_prochdl,
    const BIG_INPUT_STRC *p_inparams,
    BIG_OUTPUT_STRC *p_outparams
);

BIG_INPUT_STRC / BIG_OUTPUT_STRC содержит все виды вещей ... указатели на буферные массивы, перечисляемые параметры, целочисленные параметры и т. Д. Короче говоря, они сложны.

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

В связи с этим, как правильно передать структуры в неуправляемую DLL из C #?

Наконец, есть ли пример того, как правильно передавать буферные массивы из C # в неуправляемую DLL? В качестве альтернативы, как я могу передать двумерный массив в DLL?

Спасибо, * 1012 Грег *

Ответы [ 3 ]

3 голосов
/ 30 января 2009

Довольно просто сделать это в C # с помощью P / Invoke.

Полагаю, вам придется определять структуры данных в C # вручную.

Я бы порекомендовал вам взглянуть на эту статью MSDN по теме

2 голосов
/ 30 января 2009

Вам нужно будет широко использовать .net marshalling . Сначала вам нужно переопределить структуры C в вашем коде C #, а затем убедиться, что все правильно выполняется с использованием атрибута MarshalAs .

Если вам нужно передать указатель на структуру в C # обратно в функцию C, вы можете использовать функцию Marshal.StructToPtr .

Буферные массивы, при условии, что они определены как байты [], вы можете использовать следующую технику:

byte[] buffer = ...;
fixed(byte *pBuffer = buffer)
{
   // do something with the pBuffer
}

Оператор fixed гарантирует, что буфер не будет перемещен в память сборщиком мусора, что делает указатель внутри оператора фиксированным или закрепленным.

Что касается многомерных массивов, то это зависит от базовой реализации C, вы можете, например, работать с указателем на массив и корректировать позицию на основе количества измерений и количества элементов в каждом измерении, например:

someValue = buffer[(elementsPerDimensions * x) + y];

Из вашего описания это уже кажется довольно сложным, вы рассматривали вопрос о том, чтобы сделать вашу библиотеку удобной для COM?

0 голосов
/ 30 января 2009

Какая таблетка.

  1. Я бы не стал делать библиотеку дружественной COM. Это больше проблем, чем стоит.

  2. Я бы собрал вторую нативную библиотеку с функциями, предназначенными для P / INVOKED, чтобы собрать записи для первой и вызвать ее.

Кроме того, вы можете создать собственную / управляемую библиотеку C ++ для обработки маршалинга.

...