Ссылка на исполняемый файл в OSX
В Windows можно динамически ссылаться на исполняемый файл с экспортированными символами. Например следующий код:
// main.c
void __declspec(dllexport) interface_function() {}
int main() {}
// ext.c
void interface_function();
void extension_function() {
interface_function();
}
С
cl.exe main.c
cl.exe ext.c / LD / link main.lib
будет производить исполняемый файл main.exe
статическая библиотека main.lib
для неявного связывания и динамической библиотеки ext.dll
,
Подобное поведение может быть достигнуто в OSX с общими библиотеками:
// main.c
void interface_function() {}
int main() {}
// ext.c
void interface_function();
void extension_function() {
interface_function();
}
С
gcc main.c -o main
gcc ext.c -bundle -bundle_loader main -o ext.bundle
это практически эквивалентно настройке Windows.
Но для dynamiclib
:
> gcc ext.c -dynamiclib -o ext.dylib
а также shared
:
> gcc ext.c -shared -o ext.so
Я не могу заставить их работать из-за неопределенных символов с одной стороны и не могу загрузить исполняемый файл с -l
флаг на другой.
Я могу позволить им разрешить неопределенные символы во время выполнения с -undefined dynamic_lookup
, Но это не является устойчивым способом, потому что все ошибки соединения теперь происходят во время выполнения.
Есть ли способ предоставить список символов для динамической загрузки из исполняемого файла при ссылке как -shared
а также -dynamiclib
?
1 ответ
Да, это возможно, но тогда вы захотите создать пакет, а не общую библиотеку (см. Этот ответ для более подробной информации).
Если у вас есть основное приложение, подобное:
#include <stdio.h>
#include <dlfcn.h>
int func(void)
{
return 42;
}
int main(void)
{
void *dl = dlopen("plugin.so", RTLD_LOCAL);
if(!dl) return -1;
int (*derp)(void) = dlsym(dl, "derp");
if(!derp) return -1;
printf("derp(): %i\n", derp());
return 0;
}
clang -o main main.c -Wall -Wl,-export_dynamic
Затем вы можете скомпилировать связки против него следующим образом:
int func(void);
int derp(void)
{
return -func();
}
clang -o plugin.so plugin.c -Wall -bundle -bundle_loader ./main