Ссылка на исполняемый файл в OSX - PullRequest
0 голосов
/ 02 мая 2018

В 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 Ответ

0 голосов
/ 05 мая 2018

Да, это возможно, но тогда вам нужно будет создать комплект , а не разделяемую библиотеку (см. этот ответ для более подробной информации).

Если у вас есть основное приложение, подобное:

#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
...