You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为dlopen加载的共享库提供已链接共享库的符号?

Let's break down the problem and walk through solutions that fit your constraints.

The Root Cause

When libmain.so loads libdyn.so via dlopen("./libdyn.so", RTLD_LAZY), the default symbol lookup rules don't include symbols from libraries linked to the loader (libmain.so). Here's the breakdown:

  • libso.so is loaded as a dependency of libmain.so, but its symbols are only visible within libmain.so's scope by default.
  • By default, dlopen-ed libraries only resolve symbols from their own symbol table, the process's global symbol table (from initially loaded libraries), and libraries previously opened with RTLD_GLOBAL. Since libso.so isn't in the global table, libdyn.so can't locate foo.

Solutions (Matching Your Constraints)

Since only libmain.so is your code, and recompiling external libraries (libso.so, libdyn.so) is difficult, here are the most practical fixes:

1. Use RTLD_GLOBAL when loading libdyn.so

Modify the dlopen call in libmain.cpp to add the RTLD_GLOBAL flag:

void* handle = dlopen("./libdyn.so", RTLD_LAZY | RTLD_GLOBAL);

This loads libdyn.so into the global symbol space, allowing it to access all symbols already loaded in the process (including those from libso.so). Note: This carries a small risk of symbol conflicts if you have duplicate symbol names across libraries, but it's a quick, low-effort fix.

2. Export libso.so's symbols globally via libmain.so

Adjust the compilation of libmain.so to export symbols from its dependencies to the process's global symbol table. Update your Makefile's libmain.so rule:

libmain.so: libmain.cpp libso.so
	g++ -Wl,--no-as-needed,--export-dynamic -fPIC -shared -o libmain.so libmain.cpp -ldl -L`pwd` -lso

The --export-dynamic flag tells the linker to make all symbols from libmain.so and its dependencies (like libso.so) available in the global symbol table. When libdyn.so is loaded later, it can resolve foo from this global table. This is a cleaner solution than RTLD_GLOBAL as it avoids unnecessary global namespace pollution.

If you can recompile libdyn.so, update its compilation rule to link against libso.so:

libdyn.so: libdyn.cpp libso.so
	g++ -fPIC -shared -o libdyn.so libdyn.cpp -L`pwd` -lso

This makes libdyn.so explicitly depend on libso.so, so it will automatically resolve foo when loaded. Since you mentioned recompiling external libraries is difficult, this is a fallback option.

Verification

After applying either solution 1 or 2, recompile your project and run ./app—you should see the full expected output:

Calling main_fun...
Calling bar...
Calling foo...
Hello from foo

内容的提问来源于stack exchange,提问作者Felix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 14:52:37