共享库构造函数未执行

发布于 2024-10-31 16:05:00 字数 1514 浏览 0 评论 0原文

我有以下问题。我编写一个共享库

#include <stdio.h>
#include <stdlib.h>

static void __attribute__ ((constructor)) test_init(void);
static void __attribute__ ((destructor))  test_clean(void);

/*  Initialization  */
static void     test_init(void){
        fprintf(stderr,"initialized\n");
        fflush(stderr);
}
/*  CleanUp */
static void test_clean(void){
        fprintf(stderr,"cleaned up\n");
        fflush(stderr);
}

double  test (double x){
    return  2.0*x;
}

编译它

并使用gcc -c -fPIC testlib.c -o testlib.o

ld -shared -o libtest.so testlib.o

然后我将其包含到一个测试程序中

#include <stdio.h>
#include <stdlib.h>
extern double   test(double x);
void    main(void){

    printf("%.10e\n",test(10.0));
}

,我编译并开始使用

gcc testprog 。 c -o testprog -L。 -ltest

LD_LIBRARY_PATH=. ./testprog

然后输出为

2.0000000000e+01,

这意味着构造函数/析构函数没有被执行。另一方面,如果我编译

ar rvs testlib.a testlib.o

gcc testprog.c testlib.a -o testprog

程序的输出由

testprog 给出 已初始化 2.0000000000e+01 如果动态链接

库,为什么不执行构造函数?

我使用以下版本

GNU ld (GNU Binutils; openSUSE 11.3) 2.20.0.20100122-6 gcc 版本 4.5.0 20100604 [gcc-4_5-branch 修订版 160292] (SUSE Linux)

预先感谢您的帮助!

编辑:2011-04-13, 11:05

非常感谢luxifer,

该文档间接提供了帮助!神奇的提示是,应该通过编译器涉及链接器......

gcc -fPIC testlib.c -共享 -Wl,-soname,libtest.so -o libtest.so

有效!!!

I have the following problem. I write a shared library

#include <stdio.h>
#include <stdlib.h>

static void __attribute__ ((constructor)) test_init(void);
static void __attribute__ ((destructor))  test_clean(void);

/*  Initialization  */
static void     test_init(void){
        fprintf(stderr,"initialized\n");
        fflush(stderr);
}
/*  CleanUp */
static void test_clean(void){
        fprintf(stderr,"cleaned up\n");
        fflush(stderr);
}

double  test (double x){
    return  2.0*x;
}

And compile it using

gcc -c -fPIC testlib.c -o testlib.o

ld -shared -o libtest.so testlib.o

Then I include it into a test program

#include <stdio.h>
#include <stdlib.h>
extern double   test(double x);
void    main(void){

    printf("%.10e\n",test(10.0));
}

which I compile and start using

gcc testprog.c -o testprog -L. -ltest

LD_LIBRARY_PATH=. ./testprog

Then the output is given by

2.0000000000e+01

which means that the constructor/destructor are not executed. On the other hand, if I compile

ar rvs testlib.a testlib.o

gcc testprog.c testlib.a -o testprog

the output of the program is given by

testprog
initialized
2.0000000000e+01
cleaned up

Why are the constructors not executed if the library is linked dynamically?

I use the following versions

GNU ld (GNU Binutils; openSUSE 11.3) 2.20.0.20100122-6
gcc version 4.5.0 20100604 [gcc-4_5-branch revision 160292] (SUSE Linux)

Thank you in advance for your help!

Edited: 2011-04-13, 11:05

Thank you very much luxifer,

the document helped indirectly! The magic hint was that one should involve the linker through the compiler...

gcc -fPIC testlib.c -shared
-Wl,-soname,libtest.so -o libtest.so

works!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

oО清风挽发oО 2024-11-07 16:05:00

Gcc 的构造函数处理与 ELF 构造函数处理不同,相反,它位于 ELF 构造函数之上。要工作,您需要链接 gcc 启动文件中提供的粘合代码。

最简单的方法是使用 gcc 进行链接:

gcc -shared -o testlib.so testlib.o

Gcc's constructor handling is not the same thing as the ELF constructor handling, rather, it sits on top of it. To work, you need to link in the glue code that is provided in gcc's startup files.

The easiest way to do that is to link using gcc:

gcc -shared -o testlib.so testlib.o
念三年u 2024-11-07 16:05:00

本文仅供参考,但为了方便起见,我来您的办公室:)

我不是该领域的专家,但快速的 Google 搜索给了我这个。只阅读文档的开头,如果我猜对了,问题是这样的:

静态链接你的程序在执行时是独立的......它包含整个库,并且当你运行它时它完全加载到内存中。

当在执行时从程序调用库函数时,链接器会尝试通过查看函数是否在某个库中具有实现来解析函数上所有未解析的引用,从而动态链接。如果是这样,它会加载此实现,即仅加载函数代码。

因此,如果我得到了正确的结果,并且动态链接器仅加载库的一部分(即所需的函数),而不是整个库,那么这将解释为什么当动态链接库时不调用构造函数。

This text is meant for reference, but I'm coming over to your office for convenience :)

I'm not an expert on that field but a quick Google search gave me this. Reading just the beginning of the document and if I get it right the problem is this:

Linked statically your program is self-contained at execution time... it has the whole library in it and it's completely loaded into memory when you run it.

Linked dynamically when the library function is called from your program at execution time the linker tries to resolve all unresolved references on functions by looking if it has an implementation in some library. If so it loads this implementation, i.e. just the functions code.

So if I get this right and the dynamic linker just loads portions of libraries, i.e. needed functions, and not the whole library then this would explain why your constructor isn't called when your library is linked dynamically.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文