2010-07-14 4 views
5

У меня есть код устаревшего кода, реализованный в C (не C++). Я хотел бы иметь возможность вызвать несколько методов в этом C-коде из моего кода на C# (в Windows). Какой был бы лучший подход к интерфейсу между двумя языками? Обратите внимание, что метод в C не является апатридом. Нам нужно назвать два метода:Говоря с C от C#

  1. initialization() => это приведет к инициализации структуры данных и загрузке данных из файлов в память. Этот метод будет вызываться один раз.
  2. ComputeSomething (parameters) => с этим методом будет выполнено несколько вызовов от C#.

Примечание: Эти два метода на самом деле назвать несколько других методов, но это только два метода, которые мы хотели бы выставить на C# (код достаточно сложен, поэтому мы не хотим, чтобы порт на C#)

Я смог импортировать код c в визуальную студию и смог скомпилировать код успешно. Я знаю, что мы, возможно, можем реализовать код C как службу Windows, но я ищу решение, которое позволяет нам напрямую вызвать метод C из C#. Любые указатели высоко оценены! (COM-взаимодействие связано с тем, что я ищу?)

+0

почему не выполняют свои методы на C#? – Luiscencio

+0

Что такое скомпилированный вывод вашего кода на C? Если его .dll и поддерживает COM, вы должны просто выполнить «добавление ссылки» из Visual Studio и перейти к файлу dll. – Nate

+1

Если вы еще этого не сделали, обертывание ваших функций в COM-классе COM и использование промежуточного взаимодействия .NET/COM кажется слишком большим количеством работы/излишества. Я просто поставил эти две функции C в DLL и получил бы доступ к ним с помощью P/Invoke, как это предложил Джейсон Эванс. – stakx

ответ

10

Похоже, вы можете использовать P/Invoke для этого. Проверьте этот сайт для кончиков:

http://www.pinvoke.net/

Кроме того, попробуйте найти SO за советом по P/Invoke и Google для

C# PInvoke вызова кода С

у меня нет любые технические примеры под рукой, но я написал код .NET, который называется API Win32 через P/Invoke. Сложная часть - получение правильных сигнатур метода при передаче параметров. This может помочь вам там.

+0

Спасибо за ответ! Знаете ли вы, что P/Invoke будет работать для моей ситуации, когда вызов метода является состоятельным? (необходимо вызвать инициализацию для загрузки данных перед вызовом другого метода). Остаются ли глобальные переменные в памяти для последующего вызова метода? – mwong

+0

Рука на сердце, я не знаю. Однако, поскольку код C необходимо загружать в адресное пространство .NET-кода и оставаться резидентным (не динамически загружаемым каждый раз), я ожидал бы, что значения кода C останутся неизменными. Боюсь, вам нужно поэкспериментировать. :(Дайте нам знать, что вы узнали, и является ли моя логика совершенно неправильной! –

2

Недавняя версия Visual Studio позволяет писать код на C++, который может вызывать небезопасные функции, но по-прежнему взаимодействовать с управляемым кодом CLR. Они называют это «Неявным PInvoke» или «C++/CLR». Просмотрите статью MSDN «Using C++ Interop», чтобы узнать больше.

Управляемый код не может вызвать неуправляемый напрямую, поэтому вам нужны функции-обертки для обработки проблем управления памятью и для перевода между объектами .NET и структурами данных вашего приложения. Из приведенной выше ссылки ознакомьтесь с разделом «Как: Обернуть родной класс для использования с помощью C#».

1

Решение проблемы. Решение позволяет вызвать функцию C# из C, украсив вашу функцию атрибутом [DllExport] (напротив P/Invoke DllImport).

https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports

C# код

class Test 
{ 
    [DllExport("add", CallingConvention = CallingConvention.StdCall)] 
    public static int Add(int left, int right) 
    { 
     return left + right; 
    } 
} 

C код

int main() 
{ 
     int z = add(5,10); 
     printf("The solution is found!!! Z is %i",z); 
     return 0; 
}