如何在C ++中正确链接.so库?

时间:2018-09-04 10:45:45

标签: linux c++11 grpc dynamic-linking dlopen

我有这样的项目结构,

a.pb.h          --- includes -->    protobuf.h
b.grpc.pb.h     --- includes -->    a.pb.h & grpcpp.h

也有a.pb.ccb.grpc.cc个文件。

一个带有 extern C 的C ++包装器,它是wrapper.ccwrapper.h,其中包括b.grpc.pb.hgrpcpp.h extern C 中的函数为char* helloWorld(const char*, const char*, const char*);

创建.oa.pb.h中的b.grpc.pb.h

g++ -fpic -std=c++11 `pkg-config --cflags protobuf grpc`  -c -o a.pb.o a.pb.cc
g++ -fpic -std=c++11 `pkg-config --cflags protobuf grpc`  -c -o b.grpc.pb.o b.grpc.pb.cc

创建libcombined.so的步骤:

grpc下已经提供了protobuf/usr/local/lib。 首先创建.soa.pb.o中的b.grpc.pb.o,以将包装文件编译为:

g++ -shared -o libcombined.so *.o

编译包装为:

g++ -fpic wrapper.cc -l:./libcombined.so -c -o wrapper.o -std=c++11

{{1}中的.soa.pb.ob.grpc.pb.o中的wrapper.o

libcombined.so

将main.c编译为:

g++ -shared -o libcombinedwrapper.so *.o

我正在从gcc main.c -l:./libcombinedwrapper.so -o main -ldl 文件中调用helloWorld,文件是:

main.c

执行后出现错误:#include <stdio.h> #include <dlfcn.h> int main(){ char* (*fn)(const char*,const char*,const char*); void *handle = dlopen("path_to/libcombined.so",RTLD_NOW); if(handle==NULL){ fprintf(stderr, "Error: %s\n", dlerror()); } fn = (char* (*)(const char*,const char*,const char*))dlsym(handle, "helloWorld"); if (!fn) { /* no such symbol */ fprintf(stderr, "Error: %s\n", dlerror()); dlclose(handle); return 0; } char* msg = fn("asd","asdas","asdasd"); printf("%s",msg); return 0; }

./main

上面的第一个错误来自Error: path_to/libcombinedwrapper.so: undefined symbol: _ZN6google8protobuf2io20ZeroCopyOutputStream15WriteAliasedRawEPKvi Error: ./main: undefined symbol: helloWorld Segmentation fault (core dumped) 文件中的符号。

有人可以建议我在链接时做错了什么吗?还是protobuf.h文件中我做错了什么?

1 个答案:

答案 0 :(得分:0)

  

g++ -shared -o libcombined.so *.o

您还需要链接对象的所有依赖项(此处为libgrpc)。

您可以添加-Wl,--no-allow-shlib-undefined来验证libcombined.so是否在链接所需的所有内容

P.S。为了避免核心转储,一旦exit失败,您应该returndlopen

P.P.S。链接*.o通常是一个非常糟糕的主意。使用适当的Makefile避免不必要的编译,并明确列出要放入libcombined.so的对象。