标签: dynamic-linking

加载具有不同版本的多个共享库

我在Linux上有一个可执行文件加载libfoo.so.1(即a SONAME)作为其依赖项之一(通过另一个共享库).它还链接到另一个系统库,而该系统库又链接到系统版本libfoo.so.2.其结果是, libfoo.so.1libfoo.so.2执行期间被加载,和这应该从库版本1调用函数代码结束调用从一个较新的系统库(二进制不相容)功能与第2版,因为一些符号保持不变.结果通常是堆栈粉碎和随后的段错误.

现在,链接旧版本的库是一个封闭源的第三方库,我无法控制libfoo它编译的版本.假设,剩下的唯一选择是重建当前链接的一堆系统库以libfoo.so.2进行链接libfoo.so.1.

有没有办法避免使用链接到旧版本的本地副本替换系统库libfoo?我可以加载两个库并让代码调用正确的符号版本吗?所以我需要一些特殊的符号级版本控制?

linux versioning gcc shared-libraries dynamic-linking

16
推荐指数
2
解决办法
7205
查看次数

如何在Swift中进行弱链接?

在Objective-C中,如果我想使用仅出现在新版iOS中的特定类,我会这样做:

if( [UIBlurEffect class] ) {
  // do something with UIBlurEffect
}
else {
  // gracefully fallback to old behavior
}
Run Code Online (Sandbox Code Playgroud)

但是,等效的Swift:

if UIBlurEffect.self != nil {
  let blur: UIBlurEffect = UIBlurEffect(...)
  // ...
else {
  // ...
}

// also occurs with NSClassFromString("UIBlurEffect")
Run Code Online (Sandbox Code Playgroud)

没有相同的功能.

如果在NSNewFeature可用的环境中运行,一切都很好.但是如果未定义类,则在启动应用程序时会出现链接错误:

dyld: Symbol not found: _OBJC_CLASS_$_UIBlurEffect
Run Code Online (Sandbox Code Playgroud)

那么如何在Swift中进行弱链接?

编辑添加UIBlurEffect为特定示例.

linker objective-c dynamic-linking ios swift

16
推荐指数
1
解决办法
2856
查看次数

如何使用依赖库分发Mac OS X?

我有一个程序(特别是我的SO DevDays倒计时应用挑战的入口),它依赖于几个动态库,即libSDL,libSDL_ttf等.我/opt/local/lib通过MacPorts 安装了这些库,许多人不会安装这些库(有些人可能已经安装了这些库,但是没有安装它们).

如何分发我的程序,以便没有安装这些库的人可以开箱即用?显然我将不得不分发各种.dylib文件,但这样做是不够的.动态加载程序仍然会查找安装在我安装的位置的库.有没有办法告诉动态加载器查看可执行文件的当前目录,比如Windows对DLL的作用?人们不应该修改任何环境变量(例如DYLD_LIBRARY_PATH),因为我再次希望这可以开箱即用.

macos software-distribution dynamic-linking dyld

15
推荐指数
2
解决办法
7831
查看次数

如何从共享库中调用函数?

从共享库/ dll调用函数的最简单,最安全的方法是什么?我最感兴趣的是在linux上这样做,但如果有一个独立于平台的方式会更好.

有人可以提供示例代码来说明如何进行以下工作,用户将自己的版本编译foo到共享库中吗?

// function prototype, implementation loaded at runtime:
std::string foo(const std::string);

int main(int argc, char** argv) {
  LoadLibrary(argv[1]); // loads library implementing foo
  std::cout << "Result: " << foo("test");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

顺便说一下,我知道如何编译共享的lib(foo.so),我只需要知道在运行时加载它的简单方法.

c++ linux dll shared-libraries dynamic-linking

15
推荐指数
1
解决办法
3万
查看次数

如何减少默认的C++内存消耗?

我有一个用C++编写的服务器应用程序.启动后,它在x86 Linux上使用大约480 KB的内存(Ubuntu 8.04,GCC 4.2.4).我认为480 KB是一个过多的内存:服务器甚至没有做任何事情,没有客户端连接到服务器.(另请参阅下面的评论,其中我解释了为什么我认为480 KB是大量内存.)服务器在初始化期间唯一做的事情就是产生一个或两个线程,设置几个套接字,以及其他简单的东西.非常记忆密集.

请注意,我在谈论实际内存使用情况,而不是VM大小.我通过在空闲笔记本电脑上启动我的服务器的100个实例来测量它,并在启动服务器实例之前和之后用"免费"测量系统内存使用情况.我已经考虑了文件系统缓存和类似的东西.

经过一些测试后,看起来C++运行时中的某些东西会导致我的服务器使用这么多内存,即使服务器本身没有做任何事情.例如,如果我插入

getchar(); return 0;
Run Code Online (Sandbox Code Playgroud)

之后

int main(int argc, char *argv[]) {
Run Code Online (Sandbox Code Playgroud)

然后每个实例的内存使用量仍为410 KB!

我的应用程序仅依赖于Curl和Boost.我有很多C编程经验,我知道C库在使用之前不会增加内存消耗.

我发现的其他事情:

  • 一个简单的hello world C app消耗大约50 KB的内存.
  • 一个简单的hello world C app链接到Curl,但不使用Curl,也消耗大约50 KB的内存.
  • 一个简单的hello world C++应用程序(没有Boost)消耗大约100 KB的内存.
  • 一个简单的hello world C++应用程序包含一些Boost标头,但实际上并没有使用Boost,它消耗大约100 KB的内存.使用'nm'检查可执行文件时没有Boost符号.

我的结论如下:

  1. Gcc抛弃了未使用的Boost符号.
  2. 如果我的应用程序使用Boost,那么C++运行时(可能是动态链接器)中的某些内容会导致它使用大量内存.但是什么?我怎样才能知道这些东西是什么,我能对它们做些什么?

我记得几年前关于C++动态链接器问题的一些KDE讨论.之后的Linux C++动态链接器导致KDE C++应用程序启动时间慢,内存消耗大.据我所知,这些问题已在C++运行时修复.但类似的东西可能是我所看到的过度记忆消耗的原因吗?

来自gcc /动态链接专家的答案非常感谢.

对于那些好奇的人,有问题的服务器是Phusion Passenger的日志记录代理:https://github.com/FooBarWidget/passenger/blob/master/ext/common/LoggingAgent/Main.cpp

c++ memory-management elf dynamic-linking low-level

15
推荐指数
2
解决办法
2869
查看次数

C++ Visual Studio:使用pragma注释进行链接

我遇到了一段使用#pragma comment(lib,"libraryname")的代码.

为什么这种用法与仅从属性菜单链接库相反?在什么情况下需要这种用法?我在使用C++ Visual Studio 2010的 Windows中.

很高兴看到一个需要这种用法的例子.

c++ dynamic-linking visual-studio-2010 static-linking

15
推荐指数
3
解决办法
3万
查看次数

构建一个python模块并将其与MacOSX框架相链接

我正在尝试在MacOSX 10.6上构建一个Python扩展,并将其链接到几个框架(仅限i386).我使用distutils和Extension对象创建了一个setup.py文件.

我命令链接我的框架,我的LDFLAGS env var应该如下:

LDFLAGS = -lc -arch i386 -framework fwk1 -framework fwk2
Run Code Online (Sandbox Code Playgroud)

由于我在Extension模块文档中没有找到任何'framework'关键字,所以我使用了extra_link_args关键字.

Extension('test',
define_macros = [('MAJOR_VERSION', '1'), ,('MINOR_VERSION', '0')],
include_dirs = ['/usr/local/include', 'include/', 'include/vitale'],
extra_link_args = ['-arch i386',
                   '-framework fwk1',
                   '-framework fwk2'],
sources = "testmodule.cpp",
language = 'c++' )
Run Code Online (Sandbox Code Playgroud)

一切都在编译和链接很好.如果我从extra_link_args中删除-framework行,我的链接器将按预期失败.这是python setup.py构建产生的最后两行:

/usr/bin/g++-4.2 -arch x86_64 -arch i386 -isysroot /
-L/opt/local/lib -arch x86_64 -arch i386 -bundle
-undefined dynamic_lookup build/temp.macosx-10.6-intel-2.6/testmodule.o
-o build/lib.macosx-10.6-intel-2.6/test.so
-arch i386 -framework fwk1 -framework fwk2
Run Code Online (Sandbox Code Playgroud)

不幸的是,我刚刚制作的.so无法找到这个框架提供的几个符号.我试图用otool检查链接的框架.它们都没有出现.

$ otool -L test.so
test.so:
    /usr/lib/libstdc++.6.dylib (compatibility version …
Run Code Online (Sandbox Code Playgroud)

c++ python macos dynamic-linking

14
推荐指数
1
解决办法
5473
查看次数

使用动态链接在Linux上交叉编译Windows的Qt应用程序

为了符合Qt的LGPL许可证,使用Qt库的应用程序必须使源代码可用或动态链接到Qt(如果我用这几个字正确地得到了它).

所以我想创建一个完全正确的闭源应用程序.另外,我想在Linux(目前是Xubuntu 12.04)上使用支持C++ 11的g ++/MinGW来开发Windows二进制文件.我按照这个有用的指南来完成后者.但正如指南还指出的那样,创建了静态链接的可执行文件.

由于我使用MXE自动下载和构建Qt库(版本5.0),因此我没有太多机会影响该过程.所以我的问题是,如何创建Qt库和相应应用程序的动态链接版本?

qt cross-compiling dynamic-linking qt5 mxe

14
推荐指数
3
解决办法
7105
查看次数

ELF 重定位的应用顺序在哪里指定?

考虑 Linux 系统上的以下两个文件:

使用消息.cpp

#include <iostream>

extern const char* message;
void print_message();

int main() {
    std::cout << message << '\n';
    print_message();
}
Run Code Online (Sandbox Code Playgroud)

libmessage.cpp

#include <iostream>
const char* message = "Meow!";   // 1. absolute address of string literal
                                 //    needs runtime relocation in a .so
void print_message() {
    std::cout << message << '\n';
}
Run Code Online (Sandbox Code Playgroud)

我们可以将use_message.cpp编译为目标文件,将libmessage.cpp编译为共享库,并将它们链接在一起,如下所示:

$ g++ use_message.cpp -c -pie -o use_message.o
$ g++ libmessage.cpp -fPIC -shared -o libmessage.so
$ g++ use_message.o libmessage.so -o use_message
Run Code Online (Sandbox Code Playgroud)

的定义message …

c++ elf abi relocation dynamic-linking

14
推荐指数
1
解决办法
1656
查看次数

"未能从共享对象映射段:操作不允许"以及如何调试的可能原因是什么?

我有两个可执行文件,它们都是交叉编译的,可以在Android中运行.我已将两者放在同一目录中的设备上.我已将它们所依赖的所有共享库放在同一目录中,包括ld-linux.so.3.我使用以下命令运行可执行文件:

ld-linux.so.3 --library-path/path/to/libraries executable_name

当作为任何用户运行时,它们都适用于旧版本的Android.如果以root身份运行,两者都可以在最新版本的Android上运行.当以任何用户身份运行时,只有一个可以在最新版本的android上运行.相反,它给出:

无法从共享对象映射段:不允许执行executable_name操作

如何找出不能运行的可执行文件的不同之处?

我在网上看了很多,大多数人都会收到这个错误:

A)没有它们所依赖的库之一或可执行文件本身的执行权限.

要么

B)尝试从作为NOEXEC挂载的目录运行.

这两种情况似乎并非如此.它可以找到所有库,我可以自己加载任何库,看看它依赖于解决的其他东西.此外,我可以从感兴趣的目录运行基本脚本.

较新版本的Android,Jelly Bean,是一个不同的Linux内核版本,我想知道这是否相关.

什么给?我该如何调试?

linker executable android linker-errors dynamic-linking

13
推荐指数
3
解决办法
1万
查看次数