我尝试在Linux中创建一个共享库。当库被加载时,我如何将参数传递给函数my_load()?在我的C应用程序中,我调用test_func(),然后它会自动先执行my_load(),然后再执行my_unload()
#include <stdio.h>
void __attribute__ ((constructor)) my_load(int argc, char *argv[]);
void __attribute__ ((destructor)) my_unload(void);
void test_func(void);
void my_load(int argc, char *argv[]) {
printf("my_load: %d\n", argc);
}
void my_unload(void) {
printf("my_unload\n");
}
void test_func(void) {
printf("test_func()\n");
}
5条答案
按热度按时间dgtucam11#
您的动态库始终可以读取
/proc/self/cmdline
,以查看用于执行当前可执行文件的命令行参数是什么。example.c
:使用例如
并使用例如
(Note普通的
echo
是一个shell内置函数,您需要执行另一个类似/bin/echo
的二进制文件来加载预加载库。)但是,大多数动态库都在环境变量中接受参数;例如,
YOURLIB_MEM
用于某个内存大小提示,或者YOURLIB_DEBUG
用于在运行时期间启用详细调试输出。(My示例代码不使用stdio. h输出,因为不是所有的二进制文件都使用它,特别是用其他语言编写的时候,
wrerr()
和wrerrint()
是小而愚蠢的辅助函数,使用低级unistd. h I/O直接写入标准错误;这总是有效的,并且在运行时引起最小的副作用。有问题吗?
2w3kk1z52#
你不能。
__attribute__((constructor))
根本不支持这种情况。似乎没有任何理由不能在
main()
的开头调用my_load(argc, argv)
。您可以使用
atexit
来注册一个函数,以便在程序正常退出或从main返回时调用。tnkciper3#
AFAIK,没有办法给gcc构造函数和析构函数传递参数。你能做的最好的就是使用全局变量。
在您的示例中,您可以尝试:
主要内容:
在共享库中:
但是无论如何,只有当你通过
dlopen
显式加载共享库时,它才能工作。如果它在链接时被直接引用,构造函数将在main中的第一条指令之前被调用,你总是会在Argc
中找到原始值或0。798qvoo84#
很抱歉在这里重复一个老问题,但我刚刚在Linux和Mac OS上测试了这个问题:
它会在两个系统上打印结果:
为了让它作为一个共享库工作,我不得不添加链接器选项
-Wl,--no-gc-sections
,因为否则它会积极地删除构造函数和析构函数。esbemjvw5#
这并不使用
__attribute__ ((constructor))
语法,但如果指定一个自定义_init
函数,则可以这样做:为此,您需要传递
ld -init my_constructor
或gcc -Wl,-init,my_constructor
,例如