При создании библиотеки DLL, которая будет загружена с использованием LoadLibrary, нужно ли связывать с зависимыми двоичными файлами или достаточно включить заголовки? - PullRequest
1 голос
/ 31 марта 2020

Я создаю плагин (модуль расширения) для интерпретатора языка, на котором пишу C.

Во время выполнения программа использует LoadLibrary для загрузки указанного файла DLL. , Это похоже на работу с базовыми c DLL, которые не зависят от функций, определенных в основной программе.

Однако я пытаюсь создать подключаемый модуль DLL, который зависит от функций, определенных в двоичный файл основной программы.

Для этого я определил заголовок interface.h в базе основного кода, чтобы эти плагины включались и использовались. Он определяет заголовки для функций, которые могут им потребоваться. Плагин делает #include <interface.h> в своем заголовке.

Я скомпилирую DLL плагина следующим образом:

gcc myplugin.c -shared -Wl,--subsystem,windows -D MYPLUGIN_EXPORTS -o myplugin.dll -I..\main_program_headers

Затем я получаю следующие ошибки:

undefined reference to 'some function name'
  1. Значит ли это, что я должен скомпилировать плагины с динамическими c, связанными с фактическими двоичными файлами, от которых они зависят в основной программе?

  2. Если да, то это значит, что мне нужно хранить отдельные .o файлы основной программы, даже после привязки их к результату .exe? Может ли G CC напрямую ссылаться на файлы .o?

  3. В любом случае, я очень надеялся, что LoadLibrary позаботится об исправлении ссылок на функции при загрузке во время выполнения. Не так ли?

Обновление:

Как любезно ответил @tenfour, DLL должна следовать нормальным правилам компоновки, и ссылки на функции должны быть решено во время сборки. Он / она предложил систему, в которой хост-программа переходит в указатели плагинов для необходимой функции.

Этот подход действительно будет работать, но я все же хотел бы знать:

Какая сборка необходимо, чтобы плагин вызывал функции из основного приложения напрямую, без какой-либо специальной системы во время выполнения (кроме LoadLibrary).

Я хотел бы сказать, что моим основным источником влияния здесь является система расширения для интерпретатора CPython. Мне кажется, судя по его документации , что расширение CPython не получает указатели функций от интерпретатора хоста и все еще может напрямую вызывать функции Py_* из него.

Есть идеи, как это можно сделать? Как можно создать плагин DLL для поддержки этого? На что и как мне нужно ссылаться?

1 Ответ

0 голосов
/ 31 марта 2020

Так как вы не публиковали interface.h, я могу только догадываться, что вы там делаете функции, объявленные в прямом направлении, например:

int some_func();

Если код плагина пытается вызвать этот метод, он будет компилировать, но компоновщик не имеет ссылки на него. Тело этой функции существует только в вашем хост-приложении.

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

typedef int (*some_func_ptr)(); // declare the fn pointer type
...
some_func_ptr some_func = x; // assign it after the host passes you x
...
some_func(); // now you can call it without linker issues.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...