Я только что начал проект C # и хочу импортировать C ++ .lib и соответствующий ему файл заголовка (.h).
Я читал различные посты, в которых упоминается .dll, а не .lib, что меня смущает.
На рисунке ниже показаны файлы .lib и .h, на которые я ссылаюсь, все, что я сделал, это перетащил их в проект.
Может кто-нибудь указать мне более четкое объяснение того, как это сделать? Я уверен, что это не может быть так сложно, как кажется.
Что вы могли бы сделать, это создать оболочку C ++ / CLI и предоставить функциональность библиотеки, которую вы хотите использовать через вашу оболочку. Созданную оболочку DLL вы можете легко ссылаться в вашем проекте C #. Это, конечно, требует немного усилий для создания управляемой / неуправляемой оболочки, но в конечном итоге окупится.
Чтобы создать управляемый проект C ++, выберите в шаблонах проектов C ++ CLR и Class Library. Здесь вы можете сделать ссылку на свою библиотеку, использовать заголовочный файл так, как вы привыкли.
Затем создайте новый класс (ref class) и оберните в него свою библиотеку. Пример может выглядеть примерно так:
LibHeader.h
int foo(...);
Вы пишете класс-оболочку следующим образом:
Заголовок:
Wrapper.h
public ref class MyWrapper
{
public:
int fooWrapped();
};
Ваша реализация:
Wrapper.cpp
#include Libheader.h
int MyWrapper::fooWrapped()
{
return foo();
}
Пространства имен и все хорошие вещи опущены для простоты.
Теперь вы можете использовать MyWrapper в своем коде на C # так же просто, как и любой другой управляемый класс. Конечно, когда интерфейс библиотеки становится более сложным, вы должны подумать об этом немного больше, но это может помочь отделить код библиотеки от вашего приложения. Надеюсь пролить свет на это.
Причина в первую очередь в том, что C++
является неуправляемый язык. C#
это управляемый язык. Управляемый и неуправляемый относится к тому, как язык управляет памятью.
C++
Вы должны сделать свое собственное управление памятью (распределение и освобождение), C# .NET Framework
делает управление памятью с уборщик мусора.Вы должен убедитесь, что все места, которые вы звоните new
должен позвонить delete
и то же самое касается malloc
а также free
если вы используете C
конвенций.
Вам придется создать кучу классы обертки вокруг ваших вызовов функций, и убедитесь, что вы не утечки памяти в вашем C++
код.
Ваша главная проблема (насколько мне известно) в том, что вы не сможете вызывать эти функции прямо в C#
так как вы не можете статически связать неуправляемый код в управляемый код.
Вам придется написать .dll, чтобы обернуть все функции библиотеки в C++
, Как только вы это сделаете, вы можете использовать C#
функциональность взаимодействия для вызова этих функций из DLL.
[DllImport("your_functions.dll", CharSet = CharSet.Auto)]
public extern void your_function();
Это «так сложно, как кажется». C ++ и C # являются двойственными. У первого есть детерминированное разрушение, у второго нет. Теперь вы пишете C ++ / cli, откладывая уничтожение в каком-то финализаторе, вызываемом сборщиком мусора, работающим в своем собственном потоке, повсеместно создавая проблемы (безопасность потока, допустимы ли члены C ++ (используемые в c ++ / cli) ?, … ). Хуже того, сборщик мусора может предложить объекты C ++ крошечными (указатель) и вызвать утечку памяти (из-за позднего освобождения мелких объектов). По сути, вы заканчиваете тем, что пишете GC поверх C ++ / cli GC, чтобы удалить объекты не C ++ / cli (!) В главном потоке или другом. Все это безумие, …