在 Windows 中,要调用 DLL 中的函数,该函数必须具有显式导出声明。例如,__declspec(dllexport)或.def文件。
除了 Windows 之外,我们可以调用(共享目标文件)中的函数,.so即使该函数没有导出声明。就这一点而言,我制作 .so 比制作 .dll 容易得多。
同时,我很好奇非 Windows 如何使 .so 中定义的函数能够被其他程序调用而无需显式导出声明。我粗略地猜测 .so 文件中的所有函数都会自动导出,但我不确定。
如何找出我的程序在运行时使用的共享库的路径?
我将 glibc 2.12 作为在我的 CentOS 6.10 系统上运行的主要glibc ,并且还在/opt/glibc-2.14.
当我检查我的可执行文件时
$ objdump -p ./myProgram
Run Code Online (Sandbox Code Playgroud)
它提供了这个信息
Dynamic Section:
NEEDED libpthread.so.0
NEEDED libcurl.so.4
NEEDED libc.so.6
Run Code Online (Sandbox Code Playgroud)
我的LD_LIBRARY_PATH有这个值/opt/glibc-2.14/lib。
是否可以查看我的程序在运行时libc.so.6实际使用的库(可能是库文件的路径)?
LSB 版本: core-9.20170808ubuntu1-noarch:security-9.20170808ubuntu1-noarch
发行商 ID:Ubuntu
说明:Ubuntu 18.04.3 LTS
发布时间:18.04
代号:仿生
gcc 的 Conda 安装结果如下:
(base) userA@server:~$ conda install -c anaconda gcc
Collecting package metadata (current_repodata.json): done
Solving environment: done
## Package Plan ##
environment location: /home/userA/anaconda3
added / updated specs:
- gcc
The following NEW packages will be INSTALLED:
cloog anaconda/linux-64::cloog-0.18.0-0
gcc anaconda/linux-64::gcc-4.8.5-7
isl anaconda/linux-64::isl-0.12.2-0
Proceed ([y]/n)? y
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
ERROR conda.core.link:_execute(700): An error occurred while installing package 'anaconda::gcc-4.8.5-7'.
Rolling back transaction: done …Run Code Online (Sandbox Code Playgroud) 我制作了一个小型库(主要是下面一个更钝的库的包装器),我一直在包含的项目中编译和使用它,没有任何问题。我现在在另一个项目中使用这个库,并尝试适当地更改 CMakeLists.txt (见下文)。
cmake_minimum_required (VERSION 3.5)
set(project "foobar")
project(${project} LANGUAGES CXX)
set(${project}_VERSION_MAJOR 0)
set(${project}_VERSION_MINOR 1)
add_library(${project} SHARED
./driver/foo.h
./driver/foo.c
./bar.cpp
./bar.hpp)
set_source_files_properties(./driver/foo.c PROPERTIES LANGUAGE CXX)
target_compile_features(${project}
PUBLIC
cxx_std_11)
target_include_directories(${project} PUBLIC ./driver/ .)
set_target_properties(${project} PROPERTIES LINKER_LANGUAGE CXX)
add_executable(bno055-test
./testingProject.cpp
)
target_link_libraries(test ${project})
install(
TARGETS ${project}
RUNTIME DESTINATION bin)
Run Code Online (Sandbox Code Playgroud)
我遇到的错误与该行有关set_source_files_properties(./driver/foo.c PROPERTIES LANGUAGE CXX)。当使用上面的 C++ 标志编译这个 C 文件时,我收到许多类型的警告clang-8: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]。这是预期的,因为我使用的是已弃用的方法,并且不应使用 C++ 标志编译此文件。但是,每当我删除这一行,或将其更改为指定 C 而不是 C++ 时,我的 …
我想了解更多有关链接和共享库的信息。
最后,我想知道是否可以向共享库添加方法。例如,假设有一个源文件 ac 和一个库 lib.so (没有源文件)。为了简单起见,我们进一步假设 ac 声明了一个方法,其名称不存在于 lib.so 中。我想也许可以在链接时将 ao 链接到 lib.so,同时指示创建 newLib.so,并强制链接器将 lib.so 中的所有方法/变量导出到 newLib.so 现在基本上是lib.so 以及 a.so 中添加的方法。
更一般地说,如果有一些依赖于共享库的源文件,是否可以创建一个不再依赖于共享库的单个输出文件(库或可执行文件)?(也就是说,库中的所有相关方法/变量都将被导出/链接/内联到新的可执行文件,从而使依赖项无效)。如果这是不可能的,那么技术上是什么阻止了它呢?
这里提出了一个类似的问题:合并多个 .so 共享库。其中一个回复包含以下文本:“如果您可以访问这两个库的源文件或目标文件,则可以直接编译/链接它们的组合 SO。:无需解释技术细节。这是一个错误还是确实是否成立?如果成立,该怎么办?
compiler-construction linker shared-libraries dynamic-library
假设我有一个共享库a.so,它是由我的可执行文件第一次加载的。我的理解是,共享库文本部分被映射到VMA的中间。我有两个问题;
(1) ld.so是否会将这个共享内存文本节页面加载到物理内存,然后映射到该进程的VMA?
(2) 假设启动了使用相同共享库的第二个可执行文件a.so。ld.so会识别出这个共享库已经加载到物理内存了吗?如何理解这一点?
linux memory-management shared-libraries dynamic-linking linux-kernel
有这个文件:
\n\n加一c
\n\nint op(int i){ return i+1; }\nRun Code Online (Sandbox Code Playgroud)\n\n主程序
\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <dlfcn.h>\n\nint main(int argc, char **argv){\n if (argc<3){\n printf("usage %s <library> <number>\\n",argv[0]);\n exit(1);\n }\n\n char *lname = argv[1];\n int num = atoi(argv[2]);\n void *handle = dlopen(lname, RTLD_LAZY);\n if(!handle)\n perror("dlopen");\n\n int (*opp)(int);\n opp=dlsym(handle, "op");\n if(!opp)\n perror("dlsym");\n\n printf("number before:%i\\nnumber after:%i\\n",num,opp(num)); \n dlclose(handle);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n编译为:
\n\n$cc -fPIC -shared -o plusone.so -ldl plusone.c\n$cc -o main.exe -ldl -Wpedantic main.c\nwarning: ISO C forbids assignment between function pointer and \xe2\x80\x98void *\xe2\x80\x99 …Run Code Online (Sandbox Code Playgroud) 我有一个定义全局符号-函数的C++动态库。当我使用 gcc 编译库时,这些符号默认可见。当应用程序链接到几个库时,可能会导致符号冲突。我可以将函数放入命名空间并使用编译标志隐藏私有函数-fvisibility=hidden。那么API函数应该包含以下属性:__attribute__ ((visibility ("default")))
假设我使用 Microsoft Visual Studio 编译器在 Windows 上编译动态库。有些符号没有定义,__declspec(dllexport)是否意味着这些符号将被隐藏?
我需要更改共享库 (.so) 文件中的某些符号,如下例所示:我需要将abc.so 文件中的符号重命名为 symbol xyz。我有一个工具可以在头文件中替换它,我面临的唯一挑战是更改我的 .so 共享库。对于共享库,是否有任何工具或命令可以帮助我反汇编 .so 文件、更新符号并再次重新组装为 .so 文件?对于共享库,我们需要一种重建符号表的机制。如果有任何工具可以完成我的任务,需要帮助吗?
仅供参考:更改源是最好的方法,但对于短期的解决方案来说,它可以帮助在符号级别替换代码字。
SO标签是否能很好地代表编程语言的流行度?
我的第一个猜测是,它不是,而且它主要由杰夫的粉丝(可能是.Net偏见)和乔尔的粉丝(可能更多的C/C++偏向其他人)填充.
有没有办法获得无偏见的编程语言流行度统计?
shared-libraries ×10
c ×3
linux ×3
c++ ×2
anaconda ×1
binutils ×1
cmake ×1
conda ×1
dll ×1
dlopen ×1
gcc ×1
ld ×1
linker ×1
linux-kernel ×1
objcopy ×1
popularity ×1
readelf ×1
symbols ×1
tags ×1
visibility ×1