Как правильно связать библиотеку .so в C ++? - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть такая структура проекта,

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

Также есть файлы a.pb.cc и b.grpc.cc.

Оболочка C ++ с extern 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 что-то не так?

1 Ответ

0 голосов
/ 05 сентября 2018

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.

...