我有这样的项目结构,
a.pb.h --- includes --> protobuf.h
b.grpc.pb.h --- includes --> a.pb.h & grpcpp.h
还有a.pb.cc
和b.grpc.cc
文件。
一个带有extern C的C ++包装器,它是wrapper.cc
和wrapper.h
,包括b.grpc.pb.h
和grpcpp.h
。 extern C中的函数是char* helloWorld(const char*, const char*, const char*);
创建.o
和a.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
下提供了。首先创建了.so
和a.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
.so
,a.pb.o
和b.grpc.pb.o
的wrapper.o
为libcombined.so
:
g++ -shared -o libcombinedwrapper.so *.o
编译main.c为:
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
文件中的符号。
有人可以在链接时建议我做错了什么,或者我在main.c
文件中做错了什么?
g++ -shared -o libcombined.so *.o
您还需要链接对象的所有依赖项(此处为libgrpc
)。
您可以添加-Wl,--no-allow-shlib-undefined
来验证libcombined.so
是否链接了所需的一切。
附:为了避免核心转储,一旦exit
失败,你应该return
或dlopen
。
P.P.S.链接*.o
通常是一个非常糟糕的想法(TM)。使用适当的Makefile
来避免不必要的编译,并明确列出您打算放入libcombined.so
的对象。