Импортировать файл С++.lib и .h в проект С#?
Я только что начал проект С# и хочу импортировать С++.lib и соответствующий файл заголовка (.h).
Я читал разные сообщения, которые все упоминают .dll, а не .lib, что меня пугает.
На рисунке ниже показаны файлы .lib и .h, на которые я ссылаюсь, все, что я сделал, перетаскивает их в проект.
![enter image description here]()
Может ли кто-нибудь указать мне на более четкое объяснение, как это сделать? Я уверен, что это не может быть так сложно, как кажется.
Ответы
Ответ 1
Что вы можете сделать, это создать оболочку С++/CLI и выставить функциональность библиотеки lib, которую вы хотите использовать через вашу обертку. Созданная dll-оболочка, с которой вы можете легко ссылаться в своем проекте С#. Это, конечно, требует немного работы для создания управляемой/неуправляемой оболочки, но будет окупиться в конечном итоге.
Чтобы создать управляемый проект на С++, выберите в шаблонах проектов С++ CLR и Class Library. Здесь вы можете ссылаться на ваш lib, использовать заголовочный файл так, как вы привыкли.
Затем создайте новый класс (класс ref) и оберните в него свою библиотеку. Пример может выглядеть примерно так:
LibHeader.h
int foo(...);
Вы пишете класс обертки следующим образом:
Заголовок:
Wrapper.h
public ref class MyWrapper
{
public:
int fooWrapped();
};
Ваша реализация:
Wrapper.cpp
#include Libheader.h
int MyWrapper::fooWrapped()
{
return foo();
}
Пространства имен и все хорошие вещи опущены для простоты.
Теперь вы можете использовать MyWrapper в коде С# так же просто, как и любой другой управляемый класс. Конечно, когда интерфейс lib усложняется, вы должны думать об этом немного больше, но это может помочь разделить lib-код из вашего приложения. Надеюсь пролить свет на него.
Ответ 2
Это, к сожалению, нетривиальная проблема.
Причина в основном связана с тем, что 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();
Ответ 3
Это "так сложно, как кажется". С++ и С# являются амбивалентными. Первый имеет детерминированное разрушение, второе - нет. Теперь вы пишете С++/cli, откладывая уничтожение на какой-то финализатор, вызываемый сборщиком мусора, работающим в нем собственным потоком, представляя проблемы повсюду (безопасность потоков, члены С++ (используемые в С++/cli) действительны?,...). Еще хуже то, что GC может предложить объекты С++ быть маленькими (указатель) и спровоцировать утечку памяти (из-за позднего освобождения мелких объектов). По сути, вы заканчиваете писать GC поверх С++/cli GC для удаления объектов не С++/cli (!) В основном потоке или другом. Все это безумие,...