那些年踩过的坑

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.

https://blog.csdn.net/jq0123/article/details/71308179

发布了130 篇原创文章 · 获赞 147 · 访问量 29万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 代码科技 设计师: Amelia_0503

分享到微信朋友圈

×

扫一扫,手机浏览