我有一个静态链接到库(libA.2.0.a)的程序,并动态链接到另一个库(libB.so).libB.so还动态链接到旧版本的libA(libA.1.0.so).
这种配置是否可行?如果是这样,系统怎样知道从使用符号libA.2.0.a我的程序,并从符号libA.1.0.so的libB.so?
概述:我有一个符合标准的C++ API,它使用Boost库,我想支持它作为Windows,OS X和Linux上的本机,可静态链接的库,我想在Windows和Mono上包装.NET在OS X和Linux上.
细节:目前我已经为所有平台进行本地编译 - 这是使用标准C++和Boost.我还得到它在Windows上编译和运行C++/CLI,但我被迫使用Boost .DLLs.下一步我不知道从哪里开始,因为我从未尝试在*nix系统上使用共享库.我知道Boost在Linux上提供了共享库(我猜想在OS X上也是如此),但是这些只是在我的Visual Studios编译的C++/CLI可执行文件中自动神奇地工作,还是我需要做一些工作?MonoDevelop没有C++/CLI编译器,但据说Visual Studios编译的CLI工作得很好......这是动态链接库让我感到困惑.
我使用dlopen加载一个动态库说"lib1.so"并调用一个公开的函数说A1,A1函数使用malloc分配一个100kb的动态内存而不是释放它,在main函数中我再次dlclose.[dlopen,调用函数A1,dlclose]
我重复说了10次,Purify报告这个为1000KB的内存泄漏,valgrind报告间接丢失了1000KB.
你能否建议100 KB*10次= 1000KB,是真的内存泄漏吗?因为我调用了dlclose,所以当我们调用dlclose时,为动态库分配的所有内存都会被自动释放?
操作系统:Linux编程语言:C
我知道在加载时隐式链接到库可能会导致性能提升,因此我想知道在编译时以这种方式链接是否是一种好的做法,从而增加可执行文件大小(不可否认,这只是边际)与明确链接相比在运行时.我的问题是,当链接到位于System32中的Microsoft Windows DLL文件时,在加载时链接是否"更好",因为您可以确定库存在或遵循显式方法?
使用的语言是Delphi(pascal),有问题的库是WTsAPI32.dll - 终端服务.
编辑:正如所指出的那样 - 我选择的语言不正确并且已经修改.另外,由于在Unix中只有每一个与库有很多链接,我对可执行文件大小的评论可以省略,我当时认为我实际上是指静态链接将库代码捆绑到可执行文件中,我现在意识到这一点使用dll文件时是不可能的(DUH!).谢谢大家.
我试图通过使用dlopen和dlsym获取函数指针,但是我无法使其正常工作。尝试执行dlsym调用时失败。以下是我的代码。
有什么帮助吗?
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
int test() {
printf("%s", "test()");
return 123;
}
int main() {
char * functionname = "test";
void* handle = dlopen(NULL,RTLD_LAZY|RTLD_GLOBAL);
if (!handle) {
fprintf(stderr, "Couldn't open handle: %s\n",
dlerror());
exit(1);
}
int (*fun)() = (int (*)())dlsym(handle, functionname);
if (fun == NULL) {
fprintf(stderr, "Couldn't find function: %s\n",functionname);
exit(1);
}
int a = fun();
printf("result: %d \n", a);
}
Run Code Online (Sandbox Code Playgroud) 我一再遇到没有找到的库的问题.
在我的bashrc中我有:
LD_LIBRARY_PATH=
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib1
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib2
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib3
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH
Run Code Online (Sandbox Code Playgroud)
这些路径包含所有文件夹,我使用-L/lib1 -l1a -L/lib2 -l2a -L/lib3 -l3a将库链接到我的程序.
现在我独立开始我的程序:
./program
Run Code Online (Sandbox Code Playgroud)
精细!
然后我从mpich的mpiexec开始吧:
/mpich/intel/bin/mpiexec -np 2 ./solvertest1
Run Code Online (Sandbox Code Playgroud)
精细!
然后我启动gdb启动它:
/mpich/intel/bin/mpiexec -np 2 gdb ./solvertest1
Run Code Online (Sandbox Code Playgroud)
问题,找不到库:
Starting program: /my/program
/my/program: error while loading shared libraries: libirng.so: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我怀疑LD_LIBRARY_PATH应该通过所有子进程传播并且那些脚本和程序产生的shell会出现问题...我需要做什么才能让每个子进程(以及其他任何将被启动的)知道这些库的位置?
比方说,你编译C ++共享库libBeta.so,这使得利用预现有的C ++共享库libAlpha1.so,libAlpha2.so,libAlpha3.so,等。如果我接着写它使用C ++应用程序libBeta.so直接(并因此间接使用其它库),我要我的应用程序链接到libBeta.so只,还是应该将我的应用程序链接到所有库?
我的直觉告诉我,我应该只链接到libBeta.so,因为链接到所有库似乎libBeta.so已经是多余的,就像已经链接到其他库一样。但是,undefined reference to错误证明了我的直觉是错误的。
有人可以解释一下为什么我的直觉在某些情况下可能是错误的吗?
ps:
编辑
事实证明,我用于编译的工具在编译可执行文件和编译共享库时具有不同的行为。编译共享库时,省略了与子库的链接:(
我有一个非常简单的ELF可执行文件:
$ readelf -l ./plt.out
Elf file type is EXEC (Executable file)
Entry point 0x400338
There are 7 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x00000000003ff040 0x00000000003ff040
0x0000000000000188 0x0000000000000188 R E 8
LOAD 0x0000000000000000 0x00000000003ff000 0x00000000003ff000
0x0000000000001000 0x0000000000001000 RW 1000
INTERP 0x00000000000001c8 0x00000000003ff1c8 0x00000000003ff1c8
0x0000000000000032 0x0000000000000032 R 1
[Requesting program interpreter: /data/keno/new_glibc/usr/lib/ld-linux-x86-64.so.2]
LOAD 0x0000000000001000 0x0000000000400000 0x0000000000400000
0x00000000000003b0 0x00000000000003b0 R E 1000
LOAD 0x0000000000001ea0 0x0000000000600ea0 0x0000000000600ea0
0x0000000000000180 0x0000000000000180 RW 1000 …Run Code Online (Sandbox Code Playgroud) 意外nvml地,在Linux环境中的库路径中添加了一个不兼容的库.在我尝试查询时nvidia-smi,在该设置中,它会发出以下错误
Failed to initialize NVML: Driver/library version mismatch
当我从库路径中删除该不兼容的库并nvidia-smi再次查询时,查询成功运行并且输出按预期显示.
然而,当我通过输入ldd查看依赖库时,nvidia-smi它并未显示该过程依赖于nvml库.
$>ldd /usr/bin/nvidia-smi
linux-vdso.so.1 => (0x00007fffa84db000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f58ba044000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f58b9e3f000)
libc.so.6 => /lib64/libc.so.6 (0x00007f58b9a7e000)
librt.so.1 => /lib64/librt.so.1 (0x00007f58b9876000)
/lib64/ld-linux-x86-64.so.2 (0x00007f58ba27d000)
Run Code Online (Sandbox Code Playgroud)
如果它不依赖于nvml库,为什么在存在不兼容的nvml库时它会发出错误?
我正在尝试使用动态链接编译我的Rust项目以减小大小并在应用程序中提供.so(或Windows上的.dll)文件,就像Qt对Android一样.我读过为什么Rust可执行文件如此庞大?并编译
cargo rustc -- -C prefer-dynamic
Run Code Online (Sandbox Code Playgroud)
当我运行我的程序时,我收到此错误:
% target/debug/t_pro
target/debug/t_pro: error while loading shared libraries: libstd-a021829e87e39dcf.so: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)