微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法打开与 libprotobuf 3.5.0 ( Google Protocol Buffer ) 静态链接的共享库

如何解决无法打开与 libprotobuf 3.5.0 ( Google Protocol Buffer ) 静态链接的共享库

在命令下方构建了协议缓冲区 3.5 库。

./configure "CFLAGS=-fPIC" "CXXFLAGS=-fPIC"

创建由 libproto.a 静态链接的 libtest.so 示例库

sensor.proto 文件

Syntax = 'proto3';

message Sensor {
string name = 1;
double temperature = 2;
int32 humidity = 3;

enum SwitchLevel {
 CLOSED = 0;
 OPEN = 1;
}

SwitchLevel door = 5; 
}

test.h 文件

extern "C" void testprotocolbuffer();

test.cpp 文件

#include <iostream>
#include <fstream>
#include "sensor.pb.h"
#include "test.h"

void testprotocolbuffer()
{
    Sensor sensor;
    sensor.set_name("Laboratory");
    sensor.set_temperature(23.4);
    sensor.set_humidity(68);
    sensor.set_door(Sensor_SwitchLevel_OPEN);

    std::string s;
    sensor.SerializetoString(&s);

    std::cout << s.length() << std::endl;
}

ma​​in.cpp

#include "test.h"
#include <stdio.h>

int main()
{
testprotocolbuffer();
return 0;
}

构建步骤:

使用协议缓冲区编译器生成传感器 .h 和 .cc 文件

protobuf-3.5.0/src/protoc --cpp_out=. sensor.proto

编译 .cpp 文件( sensor.pb.cc & test.cpp )

g++ -std=c++11 -fPIC -c test.cpp sensor.pb.cc -I protobuf-3.5.0/src

使用静态链接的 lib 协议缓冲区创建共享库

 g++ -shared -pthread -o libtest.so test.o sensor.pb.o -Lprotobuf-3.5.0/src/.libs -lprotobuf

将 libtest.so 文件链接到 main.cpp

g++ -Wall -o main main.cpp -L . -ltest

执行 ./main 可执行文件时抛出错误

./main
./main: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory

请找到readelf结构

readelf -d libtest.so 

Dynamic section at offset 0x3f70a8 contains 28 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [ld-linux-x86-64.so.2]
 0x000000000000000c (INIT)               0x1e84b0
 0x000000000000000d (FINI)               0x365484
 0x0000000000000019 (INIT_ARRAY)         0x5f2540
 0x000000000000001b (INIT_ARRAYSZ)       304 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x5f2670
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x228
 0x0000000000000005 (STRTAB)             0x64910
 0x0000000000000006 (SYMTAB)             0x18a40
 0x000000000000000a (STRSZ)              1283290 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (pltGOT)             0x5f8000
 0x0000000000000002 (pltRELSZ)           214368 (bytes)
 0x0000000000000014 (pltREL)             RELA
 0x0000000000000017 (JMPREL)             0x1b3f50
 0x0000000000000007 (RELA)               0x1a4428
 0x0000000000000008 (RELASZ)             64296 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x1a4328
 0x000000006fffffff (VERNEednUM)         5
 0x000000006ffffff0 (VERSYM)             0x19ddea
 0x000000006ffffff9 (RELACOUNT)          135
 0x0000000000000000 (NULL)               0x0

能够在libtest.so上找到导出的函数

nm -gDC libtest.so  | grep "testprotocolbuffer"
000000000020b4a0 T testprotocolbuffer

即使我们静态链接到共享库,您能否帮助我解释为什么库加载失败?

解决方法

无法在运行时找到共享库路径。

ldd main
linux-vdso.so.1 =>  (0x00007fffcdba5000)
libtest.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3dcaa87000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3dcae51000)

使用 -W,R 标志构建主应用程序。

g++ -Wall -o main main.cpp -L. -ltest  -Wl,-R/local/mnt/workspace/protocolbuffer

ldd main
linux-vdso.so.1 =>  (0x00007ffc105f2000)
libtest.so => /local/mnt/workspace/protocolbuffer/libtest.so (0x00007fe6e390c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe6e3542000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fe6e315f000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe6e2f47000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe6e2d2a000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe6e3f17000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe6e2a21000)

它工作执行 ./main application

./main 
25

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。