共享对象无法在主二进制文件中找到符号,C++

发布于 2024-09-16 23:26:54 字数 1001 浏览 10 评论 0原文

我正在尝试为我编写的程序制作一种插件架构,在第一次尝试时我遇到了问题。是否可以从共享对象中访问主可执行文件中的符号?我认为以下内容就可以了:

testlib.cpp:

void foo();
void bar() __attribute__((constructor));
void bar(){ foo(); }

testexe.cpp:

#include <iostream>
#include <dlfcn.h>

using namespace std;

void foo()
{
    cout << "dynamic library loaded" << endl;    
}

int main()
{
    cout << "attempting to load" << endl;
    void* ret = dlopen("./testlib.so", RTLD_LAZY);
    if(ret == NULL)
        cout << "fail: " << dlerror() << endl;
    else
        cout << "success" << endl;
    return 0;
}

编译为:

g++ -fPIC -o testexe testexe.cpp -ldl
g++ --shared -fPIC -o testlib.so testlib.cpp

输出:

attempting to load
fail: ./testlib.so: undefined symbol: _Z3foov

显然,它不好。所以我想我有两个问题: 1)有没有办法让共享对象在加载它的可执行文件中找到符号 2)如果不是,使用插件的程序通常如何工作,以便设法获取任意共享对象中的代码以在其程序内运行?

I'm experimenting with making a kind of plugin architecture for a program I wrote, and at my first attempt I'm having a problem. Is it possible to access symbols from the main executable from within the shared object? I thought the following would be fine:

testlib.cpp:

void foo();
void bar() __attribute__((constructor));
void bar(){ foo(); }

testexe.cpp:

#include <iostream>
#include <dlfcn.h>

using namespace std;

void foo()
{
    cout << "dynamic library loaded" << endl;    
}

int main()
{
    cout << "attempting to load" << endl;
    void* ret = dlopen("./testlib.so", RTLD_LAZY);
    if(ret == NULL)
        cout << "fail: " << dlerror() << endl;
    else
        cout << "success" << endl;
    return 0;
}

Compiled with:

g++ -fPIC -o testexe testexe.cpp -ldl
g++ --shared -fPIC -o testlib.so testlib.cpp

Output:

attempting to load
fail: ./testlib.so: undefined symbol: _Z3foov

So obviously, it's not fine. So I guess I have two questions:
1) Is there a way to make the shared object find symbols in the executable it's loaded from
2) If not, how do programs that use plugins typically work that they manage to get code in arbitrary shared objects to run inside their programs?

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

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

发布评论

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

评论(2

往日情怀 2024-09-23 23:26:54

尝试:

g++ -fPIC -rdynamic -o testexe testexe.cpp -ldl

如果没有 -rdynamic (或类似的东西,如 -Wl,--export-dynamic),应用程序本身的符号将无法用于动态链接。

Try:

g++ -fPIC -rdynamic -o testexe testexe.cpp -ldl

Without the -rdynamic (or something equivalent, like -Wl,--export-dynamic), symbols from the application itself will not be available for dynamic linking.

各自安好 2024-09-23 23:26:54

来自Linux 编程接口

42.1.6 访问主程序中的符号

假设我们使用dlopen()动态加载一个共享库,使用dlsym()获取
该库中函数 x() 的地址,然后调用 x()。如果
x() 依次调用函数 y(),然后 y() 通常会在
由程序加载的共享库之一。有时,它是
理想的做法是让 x() 调用 y() 的实现
主程序。 (这类似于回调机制。)为了
为此,我们必须在主程序中创建(全局范围)符号
通过使用以下链接程序,可用于动态链接器
––export–dynamic 链接器选项:

$ gcc -Wl,--export-dynamic main.c(加上更多选项和参数)

同样地,我们可以写成
以下:

$ gcc -export-dynamic main.c

使用这些选项之一
允许动态加载的库访问全局符号
主程序。

gcc –rdynamic 选项和 gcc –Wl,–E 选项是
–Wl,––export–dynamic 的更多同义词。

From The Linux Programming Interface:

42.1.6 Accessing Symbols in the Main Program

Suppose that we use dlopen() to dynamically load a shared library, use dlsym() to obtain
the address of a function x() from that library, and then call x(). If
x() in turn calls a function y(), then y() would normally be sought in
one of the shared libraries loaded by the program. Sometimes, it is
desirable instead to have x() invoke an implementation of y() in the
main program. (This is similar to a callback mechanism.) In order to
do this, we must make the (global-scope) symbols in the main program
available to the dynamic linker, by linking the program using the
––export–dynamic linker option:

$ gcc -Wl,--export-dynamic main.c (plus further options and arguments)

Equivalently, we can write the
following:

$ gcc -export-dynamic main.c

Using either of these options
allows a dynamically loaded library to access global symbols in the
main program.

The gcc –rdynamic option and the gcc –Wl,–E option are
further synonyms for –Wl,––export–dynamic.

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