1

Попробую написать минимальный воспроизводимый пример. Есть загрузчик динамической библиотеки load.c (не могу разобраться, что он делает, но по методичке должен работать):

#include "load.h"
#include "funcs.h"
#include <stdio.h>
#include <windows.h>

void LoadRun (const char * const s) { void * lib; void (*fun)(void);

lib = LoadLibrary (s);  
fun = (void (*)(void)) GetProcAddress ((HINSTANCE) lib, &quot;func&quot;);
if (fun == NULL) printf (&quot;Cannot load function.\n&quot;);
else fun();
FreeLibrary ((HINSTANCE) lib);

}

load.h:

void LoadRun (const char * const s);

Некоторые функции для обработки данных funcs.h:

short SomeFunction (...);

Главная функция, в которой должна загружаться динамическая библиотека, после чего вызываться функция по обработке данных SomeFunction:

#include "load.h"

int main () { ... LoadRun ("SomeLib.dll"); SomeFunction (); }

При помощи компилятора GCC пытаюсь создать exe-файл программы. Есть готовые файлы SomeLib.dll, Load.dll, объектный файл программы main.o, но при вводе:

gcc -o I:\...\main.exe I:\...main.o -L./ -lLoad

появляется ошибка:

main.o: undefined reference to 'SomeFunction'

Если я правильно понимаю, компилятор пытается найти SomeFunction не в динамической библиотеке и на этапе компиляции думает, что функция не была объявлена. Как избежать этой ошибки компиляции?

Fat-Zer
  • 23,138

1 Answers1

0

В моём случае главной ошибкой было не разобраться в работе функции LoadRun.

Во-первых, функция SomeFunction вызывалась в главной функции (main), которой ничего не известно об этой функции и её расположении в памяти. Функция LoadRun получает адрес функции, загруженной из динамической библиотеки, помещает его в указатель fun и вызывает эту функцию через указатель. Можно передать указатель на SomeFunction в главную функцию и оттуда вызывать SomeFunction через этот указатель.

Во-вторых, не совпадали типы аргументов fun и вызываемой функции. Указатель fun должен иметь тот же порядок и те же типы аргументов, что и вызываемая функция SomeFunction, чтобы компилятор не ругался на неверное приведение типов при вызове GetProcAddress. Для функции SomeFunction (short * array, short size):

void (*fun)(short * array, short size);
...
fun = (void (*)(short int *, short int)) GetProcAddress ((HINSTANCE) lib, "SomeFunction");

В-третьих, как видно из примера выше, имя вызываемой функции передаётся в качестве аргумента GetProcAddress, поэтому несовпадение имён может привести к ошибке.