Вызов C-кода из управляемого кода - PullRequest
4 голосов
/ 23 октября 2010

В настоящее время у меня есть функция C, которую я хотел бы использовать в .NET (C #).

Я вижу два способа добиться этого:

  1. Компилируем его (я думаю, что это возможно) с помощью / clr на VC ++. NET, реализовав "фасадные" управляемые методы, которые вызывают код C.

  2. Компиляция кода C в виде DLL изатем вызовы API.

Что вы считаете лучшим?Как сделать первый из них?

Обновление

По запросу, вот (единственная) функция, которую мне нужно вызвать из моего управляемого кода:

int new_game(double* params1, double* params2);

Простоеще один вопрос (хотя и сложнее)

У меня есть одна функция вида

int my_hard_to_interop_function(double** input, double **output, int width);

, где вход и выход - это двумерные двойные массивы.Их ширина определяется как width, а их высота определяется функцией.Я должен вызывать этот метод C из моего приложения C #.

Ответы [ 3 ]

3 голосов
/ 23 октября 2010

Если это простой C API, то самый простой способ получить к нему доступ - это использовать PInvoke.PInvoke был разработан именно для этого сценария.

Не могли бы вы опубликовать подпись методов C?Если это так, мы могли бы предоставить соответствующие управляемые подписи.

РЕДАКТИРОВАТЬ

[DllImport("insert_the_dll_name_here")]
public static extern int new_game(ref double param1, ref double param2);

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

[DllImportAttribute("insert_the_dll_name_here"]
public static extern int M1(
  [MarshalAsAttribute(UnmanagedType.LPArray, ArraySubType=UnmanagedType.R8, SizeConst=5)] 
  double[] params1),
  [MarshalAsAttribute(UnmanagedType.LPArray, ArraySubType=UnmanagedType.R8, SizeConst=5)] 
  double[] params2) ;
1 голос
/ 25 октября 2010

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

Есть ли у вас исходный код для функций C? Если это так, вы можете легко преобразовать их в статические функции-члены ref class. Тогда вы можете использовать опцию /clr:safe и иметь чистый управляемый код.

Если у вас нет исходного кода или собственный код не может быть запущен как легко управляемый (например, использует много функций библиотеки времени выполнения C), то вы можете создать оболочку или фасад, как вы его называли. Управляемая оболочка и собственный C-код будут в конечном итоге объединяться в DLL, что упрощает развертывание, поскольку собственный путь поиска DLL не задействован.

1 голос
/ 23 октября 2010

Как утверждает JaredPar, это самый простой способ сделать это - и действительно, разработанный способ сделать это.

В частности, вам понадобится ваш вариант 2, и .dll должен быть доступен (по пути) из вашего исполняемого файла.

...