c++ - 无法打开与 libprotobuf 3.5.0(Google 协议缓冲区)静态链接的共享库
问题描述
在命令下方构建了协议缓冲区 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;
}
测试.h 文件
extern "C" void testprotocolbuffer();
测试.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;
}
主文件
#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 应用程序
./main
25
推荐阅读
- python - Postgresql 和 Python:从 SQL 中选择数据(日期时间)
- flutter - Stagehand 不支持 Dart 2.3.1 错误
- javascript - 从不解析从 Node+Express API 到 MongoDB 的 HTTP 请求
- autohotkey - ahk同时点击多个区域
- xml - 如何在 XSLT 中处理未分组但相关的数据并生成分组输出?
- r - 如何通过 shinyApp 调用位于我桌面上的应用程序?
- tensorflow - Tacotron 与 TensorFlow Lite
- java - 线程“AWT-EventQueue-0”中的异常 java.lang.ArrayIndexOutOfBoundsException:23
- ruby-on-rails - 无法启动 Rails 控制台。错误的捆绑器版本(已安装)
- android - java.lang.IndexOutOfBoundsException:索引:2,大小:0 ArrayList Kotlin