Шаги:
Разоблачи функции C++ в качестве статической библиотеки C (.lib).
Использовать операторы #pragma
для проектирования функций библиотеки в DLL.
Используйте атрибут .Net DllImport
, чтобы открыть функции библиотеки DLL.
Для примера см this github project.
Шаг 1. Создание статического проекта библиотеки. Создайте файл C++, который предоставляет каждую функцию как функцию C.
extern "C" {
void vfunc(void) { return; }
int ifunc(int i) { return i; }
}
Шаг 2. Создайте проект DLL. Укажите статическую библиотеку как «Дополнительная зависимость». Создайте файл C и поставьте операторы #pragma
для проектирования каждой статической функции lib в .DLL. Вам нужно будет определить два #pragmas, один для 32-битного и другой для 64-битного. Разница заключается в том, что для 32-битного слова перед именем функции требуется подчеркивание. Не требуется код, только #pragma
s.
#ifdef _M_X64
#define Alias(func) comment(linker, "/export:" func "=" func)
#else
#define Alias(func) comment(linker, "/export:" func "=_" func)
#endif
#pragma Alias("vfunc")
#pragma Alias("ifunc")
Шаг 3. Создайте проект .Net. Используйте атрибут DllImport
, чтобы открыть каждую функцию.
class Program
{
[DllImport("c-dll.dll")]
extern static void vfunc();
[DllImport("c-dll.dll")]
extern static void ifunc();
static void Main(string[] args)
{
vfunc();
int i = ifunc(1);
}
}
Хотя кодирование просто с помощью этих методов, вам нужно сделать совсем немного редактирования решений и файлов проекта.
Установить правильный порядок сборки решения. DLL будет зависеть от статической библиотеки. Проекты .Net будут зависеть от DLL.
Вручную отредактируйте файл проекта DLL для создания 32-разрядных и 64-разрядных библиотек DLL в отдельные каталоги (например, Win32 \ Debug, x64 \ Debug).
Вручную отредактируйте файлы проекта .Net для создания разделов для комбинаций x86/x64 и Debug/Release (всего 4). НЕ ИСПОЛЬЗУЙТЕ AnyCPU
. DllImport
НЕ РАБОТАЕТ С AnyCPU
. ИСПОЛЬЗУЙТЕ ТОЛЬКО x86/x64.
Вручную отредактируйте путь вывода файла проекта .Net, чтобы быть тем же самым каталогом Win32/x64, как указано выше. Это позволит DllImport
найти DLL, поскольку DLL/EXE использует один и тот же каталог. При желании вы можете поместить DLL в каталог для обнаружения или поместить путь в DllImport, но это проблематично, если вы используете две библиотеки DLL (32/64).
Это ошибка, имя, которое используется компилятором C++, очень полезно для обеспечения того, чтобы при изменении объявления функции ничего не изменилось.Дисбаланс стека это вызывает чрезмерно уродливую проблему для устранения неполадок. В противном случае, иначе, иначе, чем «extern» C '' в объявлении функции, маркерщик pinvoke уже знает, как искать нормальные декодеры функций C. –