c - 在 GNU GCC 和 clang 中使用外部头文件创建共享库
问题描述
对于我的这个问题,我的目标是创建一个软件,main
它需要一个插件,libfunc.so
并且libfunc.so
会修改burger
.
主.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;
}
main.h的声明burger
:
#ifndef MAIN_H__
#define MAIN_H__
extern int burger;
#endif
和插件 [ func.c ] 如下:
#include <stdio.h>
#include "main.h"
void some_func(){
burger += 10;
}
用clang编译了所有这些,我没有收到错误:
$ clang -rdynamic main.c -o main
$ clang -shared -fPIC func.c -o libfunc.so
但是 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'
是的,我试过删除extern
它,它编译成功,但输出是:
$ ./main.exe
before ptr_func 3
after 3
另一方面,clang 成功编译并按我的预期工作:
$ ./main
before ptr_func 3
after 13
和没有extern
编译的一样clang
难道这两个对手真的不喜欢一致吗?
这是它的要点https://gist.github.com/harieamjari/8c816f39fe04d38d83022301872272ea
附加说明: 我的叮当声来自 Termux。(一个模拟 linux 的 android 应用程序)。我拥有的 gcc 来自 cygwin。
gcc 版本 9.3.0
铿锵声版本 9.0.0
注意 从我的 Termux 中,我安装了 gnu-8 并编译了上面的 MWE,但我没有遇到错误。
也许我应该为此使用 Windows.h 而不是在 cygwin 中使用 dlfcn.h。
解决方案
推荐阅读
- python - 修改函数以接受表格(Python 3)
- amazon-web-services - 当我将实例类型从 t2 micro 更改为 t3a.xlarge 时会发生什么?
- actionscript-3 - 如何在一个数组中命中测试相同的对象?
- java - Spring MVC 组件扫描不拾取控制器
- java - Int++ 运算符在第一次运行时没有增加 int
- amazon-web-services - 如何隐藏 terraform aws_ssm_parameter 值
- r - 如何通过匹配r中另一个数据帧的ID来仅替换NA
- loopbackjs - How to implement rabbit mq or bull js in loopback 4
- spring-boot - Spring-boot + Ignite 在 cassandra 中创建空值墓碑
- django - 在为我的 postgreSQL 数据库创建用户时。我收到错误 su:无法识别术语“su”