This is theoretical question. I am aware that perhaps best practice would be the use of shared libraries. But I ran into this question and cannot seem to find an answer anywhere.
How to construct the code and compile in ELF format a program in C/C++ so that it can be loaded with dlopen()
?
For example if one executable contains implementation of some function int test()
and I would like to call this function from my program (and preferably get the result of function), if that is even possible, how would I go about doing that?
In pseudocode I could describe it as follows:
ELF executable source:
void main() {
int i = test();
printf("Returned: %d", i);//Prints "Returned: 5"
}
int test() {
return 5;
}
External program:
// ... Somehow load executable from above
void main() {
int i = test();
printf("Returned: %d", i);//Must print "Returned: 5"
}
Based on links provided in comments and other answers here is how it can be done without linking these programs compile time:
test1.c:
#include <stdio.h>
int a(int b)
{
return b+1;
}
int c(int d)
{
return a(d)+1;
}
int main()
{
int b = a(3);
printf("Calling a(3) gave %d \n", b);
int d = c(3);
printf("Calling c(3) gave %d \n", d);
}
test2.c:
#include <dlfcn.h>
#include <stdio.h>
int (*a_ptr)(int b);
int (*c_ptr)(int d);
int main()
{
void* lib=dlopen("./test1",RTLD_LAZY);
a_ptr=dlsym(lib,"a");
c_ptr=dlsym(lib,"c");
int d = c_ptr(6);
int b = a_ptr(5);
printf("b is %d d is %d\n",b,d);
return 0;
}
Compilation:
$ gcc -fPIC -pie -o test1 test1.c -Wl,-E
$ gcc -o test2 test2.c -ldl
Execution results:
$ ./test1
Calling a(3) gave 4
Calling c(3) gave 5
$ ./test2
b is 6 d is 8
References:
PS: In order to avoid symbol clashes imported symbols and pointers they assigned to better have different names. See comments here.