For this question of mine, my goal was to create a software, main
, that takes a plugin, libfunc.so
, and libfunc.so
would modify the value of burger
.
main.c :
#include <stdio.h>
#include <stdlib.h> // for exit()
#include <dlfcn.h>
#include "main.h"
int burger = 3;
int main(){
void (*ptr_func)();
void *handle;
handle = dlopen("./libfunc.so", RTLD_NOW);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
*(void**)(&ptr_func) = dlsym(handle, "some_func");
if (!ptr_func){
fprintf(stderr, "%s\n", dlerror());
dlclose(handle);
exit(1);
}
printf("before ptr_func %d\n", burger);
ptr_func();
printf("after %d\n", burger);
return 0;
}
The declaration of burger
,
main.h:
#ifndef MAIN_H__
#define MAIN_H__
extern int burger;
#endif
and the plugin [func.c] as this:
#include <stdio.h>
#include "main.h"
void some_func(){
burger += 10;
}
compiled all of these with clang and I got no error:
$ clang -rdynamic main.c -o main
$ clang -shared -fPIC func.c -o libfunc.so
But the problem arises with gcc:
$ gcc -rdynamic main.c -o main
$ gcc -shared -fPIC func.c -o libfunc.so
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: /tmp/cc
vgKpEc.o:func.c:(.rdata$.refptr.burger[.refptr.burger]+0x0): undefined reference
to `burger'
Yes, I've tried removing the extern
and it compiled successfully but the output was:
$ ./main.exe
before ptr_func 3
after 3
clang on the other hand compiled this successfully and working as I expected:
$ ./main
before ptr_func 3
after 13
The same as without extern
compiled in clang
Do this two rivals really don't like to be consistent?
Here's the gist of it https://gist.github.com/harieamjari/8c816f39fe04d38d83022301872272ea
Additional notes: The clang I have was from Termux. (an android application that simulates linux). And the gcc I have was from cygwin.
gcc version 9.3.0
clang version 9.0.0
NOTICE From my Termux, I installed gnu-8 and compiled the MWE above, but I do not experience an error.
Maybe I should use Windows.h for this matter instead of using dlfcn.h in cygwin.