在C++中创建类库时,可以在动态(.dll
,.so
)和静态(.lib
,.a
)库之间进行选择.它们之间有什么区别,何时适合使用哪种?
在某些情况下,是否有任何令人信服的性能原因选择静态链接而不是动态链接?我已经听过或读过以下内容,但我对这个问题的了解不足以保证它的真实性.
1)静态链接和动态链接之间的运行时性能差异通常可以忽略不计.
2)(1)如果使用使用配置文件数据优化程序热路径的配置文件编译器,则不成立,因为使用静态链接,编译器可以优化代码和库代码.通过动态链接,您的代码可以进行优化.如果大部分时间都花在运行库代码上,那么这可能会产生很大的不同.否则,(1)仍然适用.
我在使用C++中的静态方法时遇到了一些麻烦
示例.h:
class IC_Utility {
public:
IC_Utility();
~IC_Utility();
std::string CP_PStringToString( const unsigned char *outString );
void CP_StringToPString( std::string& inString, unsigned char *outString, short inMaxLength );
static void CP_StringToPString( std::string& inString, unsigned char *outString);
void CP_StringToPString( FxString& inString, FxUChar *outString);
};
Run Code Online (Sandbox Code Playgroud)
示例.cpp:
static void IC_Utility::CP_StringToPString(std::string& inString, unsigned char *outString)
{
short length = inString.length();
if( outString != NULL )
{
if( length >= 1 )
CPLAT::CP_Utility::CP_CopyMemory( inString.c_str(), &outString[ 1 ], length );
outString[ 0 ] = length;
}
}
Run Code Online (Sandbox Code Playgroud)
我想拨打电话:
IC_Utility::CP_StringToPString(directoryNameString, …
Run Code Online (Sandbox Code Playgroud) 即使是简单的小型Haskell程序也会变成巨大的可执行文件.
我已经编写了一个小程序,它被编译(用GHC)到二进制文件,大小扩展到7 MB!
甚至可以将一个小的Haskell程序编译成巨大的二进制文件?
如果有的话,我可以做些什么来减少这个?
我不得不承认,随着iOS 8的发布,我对iOS中的动态和静态框架感到有些困惑.
我正在寻找一种方法来分发我创建的库,我需要支持iOS 7及更高版本.(注意:这将是一个专有框架.我不能使用可可豆荚,我也不能分发来源).这是我已经知道的:
以下是关于此信息的问题:
frameworks static-libraries static-linking ios ios-frameworks
我在网上看到以下组合存在:
专有源代码+ GPL源代码 - > GPL源代码(所有代码必须在GPL下发布)
专有源代码+ LGPL源代码 - >专有源代码(所有代码仍为专有)
现在静态/动态链接GPL和LGPL代码如何与上述组合一起工作?
事实上,Linux上的-static gcc标志现在不起作用.让我引用GNU libc FAQ:
2.22.即使是静态链接的程序也需要一些我不能接受的共享库.我能做什么?
如果没有共享库,{AJ} NSS(详细信息只需输入`info libc"Name Service Switch"')将无法正常工作.NSS允许通过仅更改一个配置文件(/etc/nsswitch.conf)而不重新链接任何程序来使用不同的服务(例如NIS,文件,db,hesiod).唯一的缺点是现在静态库需要访问共享库.这由GNU C库透明地处理.
解决方案是使用--enable-static-nss配置glibc.在这种情况下,您可以创建一个仅使用服务dns和文件的静态二进制文件(为此更改/etc/nsswitch.conf).您需要明确链接所有这些服务.例如:
Run Code Online (Sandbox Code Playgroud)gcc -static test-netdb.c -o test-netdb \ -Wl,--start-group -lc -lnss_files -lnss_dns -lresolv -Wl,--end-group
这种方法的问题在于您必须将使用NSS例程的每个静态程序与所有这些库链接起来.
{UD}事实上,不能再说使用此选项编译的libc正在使用NSS.没有开关了.因此,强烈 建议不要使用--enable-static-nss,因为这会使系统上程序的行为不一致.
关于这个事实,现在有什么合理的方法可以在Linux上创建一个功能齐全的静态构建,或者静态链接在Linux上完全没用?我的意思是静态构建:
编译静态链接静态库的共享对象时遇到了很多问题.此问题仅出现在x84_64平台上.在x86_32上进行相同的编译工作时,我没有任何问题.
也许这是一个特定于操作系统的GCC配置,但我的研究表明它是如何在x86_64平台上运行GCC的.无论如何,我在Ubuntu 10.04 x86_64上使用gcc 4.4.3.
问题是如何解决的?...确保使用-fPIC编译所有静态库依赖项.
问题1: -fpic和-fPIC之间有什么区别(显然-fPIC会在x86上生成更多指令)?为什么后一种类型在x86_64上下文中更相关?
问题2:我的假设是,当您链接静态代码时,您在链接时将函数硬连接到二进制文件中,为什么它需要"位置无关代码"机制提供的间接级别?
问题3:现在如果x86不需要-fpic/-fPIC来链接共享对象与静态存档,为什么在x86_64中需要它?
问题4:即使需要,为什么不隐式提供?我认为突破性变化应该是一个很大的禁忌
gcc compilation dynamic-linking gnu-toolchain static-linking
我有一个静态库文件libunp.a
,我知道我可以gcc -lunp xx
用来链接到库.
我可以#pragma comment(lib,"xxx.lib")
用来告诉Microsoft C/C++编译器包含库; 我怎么能在Linux/GCC下做到这一点?
static-linking ×10
c++ ×4
gcc ×3
linker ×2
c ×1
c# ×1
compilation ×1
dll ×1
frameworks ×1
ghc ×1
glfw ×1
glibc ×1
gpl ×1
haskell ×1
ios ×1
lgpl ×1
linux ×1
open-source ×1
performance ×1