我有这样的项目结构,
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
{{1}中的.so
,a.pb.o
和b.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
文件中我做错了什么?
答案 0 :(得分:0)
g++ -shared -o libcombined.so *.o
您还需要链接对象的所有依赖项(此处为libgrpc
)。
您可以添加-Wl,--no-allow-shlib-undefined
来验证libcombined.so
是否在链接所需的所有内容。
P.S。为了避免核心转储,一旦exit
失败,您应该return
或dlopen
。
P.P.S。链接*.o
通常是一个非常糟糕的主意。使用适当的Makefile
避免不必要的编译,并明确列出要放入libcombined.so
的对象。