mingw库在VS下的使用
LDFLAGS += -static-libgcc -static-libstdc++
LDFLAGS += -Wl,-Bstatic -lstdc++ -lpthread
LDFLAGS += -Wl,--out-implib,xxx.lib,--output-def,xxx.def
$(CXX) $(CXXFLAGS) $^ -o $@.dll $(LDFLAGS)
通过上述Makefile可以在mingw下生成dll和对应的lib、def文件,且没有任何mingw库的依赖;
单独在VS下链接运行也是OK的,但一旦和其它mingw编译的库同时使用,链接时没问题,运行时却会跳出无法定位函数的错误提示框;
解决方案:
使用windows命令行下的lib命令,根据def文件重新导出lib文件,重新链接,运行正常;
lib /DEF:xxx.def /MACHINE:X86 /OUT:xxx.lib
具体导致原因未知,需要研究lib导入库原理,网上对其原理解释很少,《程序员的自我修养》动态库的导入、装载、运行一章中或可以找到答案;
gcc链接库顺序导致的undefined reference
gcc在链接过程中,对链接顺序是有要求的,库的加载顺序是从右往左的,也就是右边的库先加载,左边的库后加载,当然这是历史遗留导致,这样做一来是为了防止链接多余的库导致生成目标文件变大,二来是防止循环查找符号增加链接时间
以下面为例
gcc main.c -o main -llibx -lliby
链接器首先加载liby的符号表,然后加载libx,如果liby依赖于libx,则会出现undefined reference “libx func”的错误
所以在写Makefile时,链接库顺序很重要,一个原则是
-l上层库 -l底层库 -l系统库
如果实在搞不清楚各个库间的依赖关系怎么办,链接器提供了重复查找的选项"-(" -llibs "-)"
,在gcc选项中使用-Xlinker
将其传入,整体写法如下:
gcc main.c -o main -Xlinker "-(" -llibx -liby "-)"
当然循环查找可能会增加链接时间,建议在依赖库都写上后如果出现undefined reference错误时,先使用-Xlinker
先尝试下,如果使用-Xlinker
后链接是OK的,那就可以判定是链接库顺序导致的,后续再搞清库依赖关系,不断调整链接顺序即可,如果不OK,则是还有依赖库未写上。
protobuf运行报错
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
Aborted (core dumped)
gdb分析core文件,发现崩溃在call_once<std::once_flag&, void (&)()> () at ./google/protobuf/stubs/once.h:91
经分析,call_once是调用pthread_once实现,故链接库加上-lpthread
,问题解决
grpc不支持多次异步写
grpc提供的异步接口并非真正的异步接口,只能有序读写,等待完成队列通知返回后才能进行下一次读写,同时多次读写会导致程序中断Abort,Write接口上注释如下:
/// Only one write may be outstanding at any given time. This means that
/// after calling Write, one must wait to receive \a tag from the completion
/// queue BEFORE calling Write again.