dll — C ++ GetProcAddress () не может найти метод статического класса

Мне нужно динамически загрузить DLL в C ++.

Я следовал этому уроку http://msdn.microsoft.com/en-us/library/ms235636.aspx создать dll и все работало нормально.

Затем я последовал за этим http://msdn.microsoft.com/en-us/library/64tkc9y5.aspx и я адаптировал консольное приложение следующим образом:

typedef DOUBLE(CALLBACK* DllFunc)(DOUBLE, DOUBLE);

int _tmain(int argc, _TCHAR* argv[])
{
HINSTANCE hDLL;               // Handle to DLL
DllFunc dllFunc1;
DOUBLE p1 = 1.0, p2 = 2.0, r;
hDLL = LoadLibrary(L"MathFuncsDLL");
if (hDLL != NULL)
{
cout <<  "DLL loaded: " << hDLL << endl;
dllFunc1 = (DllFunc)GetProcAddress(hDLL, "MyMathFuncs@MathFuncs@Multiply");
if (!dllFunc1)
{
// handle the error
FreeLibrary(hDLL);
cout << "Function not found!" << endl;
return -1;
}
else
{
// call the function
r = dllFunc1(p1, p2);
cout << "The result is: " << r << endl;
}
}
else {
cout << "Dll not found" << endl;
return -1;
}
cout << "Press any key to exit." << endl;
int i;
cin >> i;
return 0;
}

DLL загружена правильно и не является нулевой. Проблема в функции GetProcAddress (), которая всегда возвращает 0.

Я пробовал с каждой комбинацией пространства имен, имени класса, имени метода. Я попытался использовать оператор области (: 🙂 вместо @ в имени функции.

Я пытался определить все пространство имен как
extern «C», но ничего не меняется. Каждый раз, когда я запускаю или отлаживаю консольное приложение, оно не может найти функцию «Умножить».

Я думаю, что я что-то упустил …
Где я не прав?


РЕДАКТИРОВАТЬ

Зависимость Уокер выставил мне следующую таблицу экспорта:

Таблица экспорта DLL

Теперь мне интересно, что означает последняя часть имени функции …
Почему __declspec (dllexports) добавляет эти символы?

-1

Решение

Используйте такой инструмент, как dumpbin или Dependency Viewer, чтобы проверить экспортированные имена функций. Это позволит вам определить, какой из возможных режимов отказа относится к вашему случаю:

  1. Функция не экспортируется, или
  2. Функция экспортируется, но имя оформлено, или
  3. Функция экспортируется с именем, которое вы ожидали, но вы просто ввели его неправильно.
2

Другие решения

Добро пожаловать в C ++. Все, что компилятор добавляет к именам ваших функций, это гарантирует, что каждая функция с уникальной подписью имеет уникальное имя. Microsoft называет искажение имен одним способом, а GCC / Clang — другим. Он не стандартизирован, но все компиляторы в конкретной ОС одинаково именуют друг друга, поэтому они могут уживаться друг с другом.

Единственный способ обеспечить предсказуемость вашего имени людьми — объявить экспортированную функцию DLL как extern "C", Тем не менее, это ограничивает вас для экспорта функций C.

В библиотеках, над которыми я работал, есть одна экспортированная функция C, которая инициализирует библиотеку и возвращает указатель на интерфейс. В этом случае «интерфейс» означает абстрактный виртуальный базовый класс без данных и только виртуальные функции.

Это правильный способ объявить интерфейсный класс:

struct my_interface
{
virtual int my_function1( int param1, int param2 ) = 0;
virtual int my_function2( const char *param ) = 0;

#if CHOOSE_DESTRUCTION_TYPE

protected:
// Protected non-virtual destructor prevents the use of delete on the interface pointer.
// Must be defined because it will be used as objects of derived types are destructed.
~my_interface() {};

#else

// Public virtual destructor allows the use of delete on the interface pointer.
virtual ~my_interface() = 0;

#endif

private:
// Private copy assignment prevents "*ptr1 = *ptr2".
// This odd syntax CAN be supported, but you probably shouldn't.
// Only needs to be declared because nobody can call it.
my_interface & operator=( const my_interface & );

// Ditto for move assignment.
my_interface & operator=( my_interface && );
};
3

По вопросам рекламы [email protected]