Проблемы с переносом C++ DLL из C#
Я использую System.Runtime.InteropServices для вызова нескольких функций, написанных на C++, из моего приложения на C#. У меня просто проблемы с конкретной функцией, которая возвращает массив.
Я видел, что моя функция не должна ничего возвращать, и указатель на "возвращаемую переменную" должен быть en entry. Но я не могу сделать это правильно.
Например, если у меня есть функция в C++
void func(double *y, double *x){...}
который манипулирует массивом х и возвращает массив у.
Я делаю:
в моем.h:
extern "C" __declspec(dllexport) void func(double *y,double *x);
-в моем.cpp:
__declspec(dllexport) void func(double *y,double *x){...}
-в моем коде C#:
static class AnyClass
{
[DllImport(dllPath)]
public extern static void func(out double[] y, double[] x);
int otherfunc
{
double[] x = new double[5];
double[] y = new double[5];
...
func(out y, x);
}
}
но это дает мне System.EntryPointNotFoundException.
Любая подсказка?
3 ответа
EntryPointNotFoundException означает, что в вашей DLL не найдено ничего с именем 'function'.
В вашем.h файле вы называете это 'func'. Но в вашем.cpp файле вы называете это "функцией". И так как ваш.h файл является единственным местом, которое объявляет extern "C"
эффективно происходит то, что функция экспортируется вашей DLL C++-style-name-mangled, а не plain-c-style. Поэтому, когда C# ищет "функцию" в стиле обычного c, он не может ее найти.
Я думаю, вы также должны указать extern "C"
в вашем.cpp файле. Если нет, вы можете в конечном итоге с двумя различными функциями func
тот, который с правильной связью только объявлен и не определен.
Примечание: Afair the extern "C"
linkage также указывает, как называются функции в DLL-файле. Для функций C++ некоторые пред. Постфиксы добавляются к имени, относящемуся к подписи (т. е. параметры и тип возвращаемого значения). Это необходимо, потому что вы можете перегружать функции в C++. Поэтому, если вы не укажете extern "C"
функции называются по-разному в DLL и, следовательно, не могут быть найдены управляемым кодом.
EntryPointNotFoundException
означает, что во время выполнения не удалось найти указанное имя функции в вашей DLL.
Возможные причины
- Вы неправильно написали имя функции в вашей DLL или вашей программе
- Вы не деактивировали название искажения (
extern "C"
)
Первую причину легко найти, просто перепроверьте все имена и убедитесь, что они действительно равны. Если по какой-либо причине вы не можете изменить DLL, но, как и другое имя из C#, вы можете использовать свойство DllImportAttribute.EntryPoint, чтобы указывать на функцию с другим именем.
Второе сложнее найти. Чтобы диагностировать проблему, я предлагаю вам использовать Dependency Walker, чтобы увидеть, что на самом деле происходит внутри вашей скомпилированной DLL. Используя этот инструмент, вы можете увидеть имена функций, а также, являются ли они C++ или нет.
Вы уже пытались использовать extern "C"
чтобы убедиться, что имя функции не влияет на искажение имени. Возможно, вы не включили файл.h из вашего файла.cpp, чтобы компилятор не видел extern "C"
совсем.