Reputation: 5675
On Windows it is possible to dynamically link to an executable with exported symbols. For example following code:
// main.c
void __declspec(dllexport) interface_function() {}
int main() {}
// ext.c
void interface_function();
void extension_function() {
interface_function();
}
With
cl.exe main.c
cl.exe ext.c /LD /link main.lib
would produce an executable main.exe
, a static library main.lib
for implicit linking, and a dynamic library ext.dll
.
Similar behavior can be achieved in OSX with shared libraries:
// main.c
void interface_function() {}
int main() {}
// ext.c
void interface_function();
void extension_function() {
interface_function();
}
With
gcc main.c -o main
gcc ext.c -bundle -bundle_loader main -o ext.bundle
it is virtually equivalent to the Windows setup.
But for dynamiclib
:
> gcc ext.c -dynamiclib -o ext.dylib
and shared
:
> gcc ext.c -shared -o ext.so
I cannot get them to work because of undefined symbols on one hand and unable to load an executable with -l
flag on the other.
I can let them resolve undefined symbols in runtime with -undefined dynamic_lookup
. But this is not a sustainable way because all the link errors are now happening in run-time instead.
Is there a way to provide the list of symbols to dynamically load from an executable when linking as -shared
and -dynamiclib
?
Upvotes: 3
Views: 727
Reputation: 23850
Yes this is possible, but then you'll want to create a bundle rather than a shared library (see this answer for more detail).
If you have a main application like so:
#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
Then you can compile bundles against it like so:
int func(void);
int derp(void)
{
return -func();
}
clang -o plugin.so plugin.c -Wall -bundle -bundle_loader ./main
Upvotes: 1