如何编译ELF二进制文件以便可以将其作为动态库加载? [英] How to compile ELF binary so that it can be loaded as dynamic library?

查看:80
本文介绍了如何编译ELF二进制文件以便可以将其作为动态库加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是理论问题.我知道,也许最佳实践是使用共享库.但是我遇到了这个问题,似乎无法在任何地方找到答案.

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.

如何构造代码并以ELF格式编译C/C ++程序,以便可以使用 dlopen()加载该程序?

How to construct the code and compile in ELF format a program in C/C++ so that it can be loaded with dlopen()?

例如,如果一个可执行文件包含某些函数 int test()的实现,而我想从程序中调用此函数(最好获取函数的结果),即使有可能,我该怎么做呢?

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可执行文件源:

ELF executable source:

void main() {
    int i = test();
    printf("Returned: %d", i);//Prints "Returned: 5"
}

int test() {
    return 5;
}

外部程序:

// ... 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;
}

编译:

$ gcc -fPIC  -pie -o test1 test1.c -Wl,-E
$ gcc -o test2 test2.c -ldl

执行结果:

$ ./test1
Calling a(3) gave 4 
Calling c(3) gave 5
$ ./test2 
b is 6 d is 8

参考:

PS :为了避免符号冲突,导入的符号和分配给它们的指针最好具有不同的名称.在此处查看评论.此处.

PS: In order to avoid symbol clashes imported symbols and pointers they assigned to better have different names. See comments here.

这篇关于如何编译ELF二进制文件以便可以将其作为动态库加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆