Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
构建一个使用协议缓冲区的Android可执行gRPC服务器(无APK)_Android_C++_Android Ndk_Protocol Buffers_Grpc - Fatal编程技术网

构建一个使用协议缓冲区的Android可执行gRPC服务器(无APK)

构建一个使用协议缓冲区的Android可执行gRPC服务器(无APK),android,c++,android-ndk,protocol-buffers,grpc,Android,C++,Android Ndk,Protocol Buffers,Grpc,我从中编译了gRPC Android示例 我想从adb shell以可执行文件的形式运行该程序 将这些行添加到grpc helloworld.cc: #include <iostream> int main() { std::cout << "qwerty" << std::endl; return 0; } 然后我推送生成的可执行文件和libs文件并尝试运行它: LD_库_路径=/鳄梨 我得到了以下错误: [libprotobuf致命 /home

我从中编译了gRPC Android示例

我想从adb shell以可执行文件的形式运行该程序

将这些行添加到
grpc helloworld.cc

#include <iostream>

int main() {
  std::cout << "qwerty" << std::endl;
  return 0;
}
然后我推送生成的可执行文件和libs文件并尝试运行它:

LD_库_路径=/鳄梨

我得到了以下错误:

[libprotobuf致命 /home/buga/grpc/third_party/protobuf/src/google/protobuf/stubs/common.cc:79] 该程序是根据3.0.0版协议缓冲区编译的 运行时库,它与安装的版本不兼容 (3.5.1). 请与程序作者联系以获取更新。如果你编译 如果您自己要启动该程序,请确保您的标题来自同一个 作为链接时间库的协议缓冲区版本。(版本 中的验证失败 “out/soong/.intermediates/frameworks/av/drm/libmediadrm/libmediadrm/android_arm64_armv8-a_kryo300_shared_core/gen/proto/frameworks/av/drm/libmediadrm/protos/plugin_metrics.pb.cc”。)终止 带有类型为google::protobuf::FatalException的未捕获异常:此 该程序是根据3.0.0版协议缓冲区编译的 运行时库,它与安装的版本不兼容 (3.5.1). 请与程序作者联系以获取更新。如果你编译 如果您自己要启动该程序,请确保您的标题来自同一个 作为链接时间库的协议缓冲区版本。(版本 中的验证失败 “out/soong/.intermediates/frameworks/av/drm/libmediadrm/libmediadrm/android_arm64_armv8-a_kryo300_shared_core/gen/proto/frameworks/av/drm/libmediadrm/protos/plugin_metrics.pb.cc”。) 流产

我做错了什么


我们意识到有一个protobuf库的版本名为
libprotobuf cpp full.so
libprotobuf cpp lite.so
,它们的版本似乎是3.0.0。这与我们的版本(3.5.1)相冲突,该版本被编译成静态库或共享库。

我不太清楚为什么会发生这种情况。链接器加载
helloworld\u proto\u lib
后,会覆盖所有加载的protobuf符号,并且由于某种原因,与您无关的另一个库会使程序崩溃。但这并没有告诉你什么新鲜事

以下是解决此问题的一种方法:

1.对grpc-helloworld.cc的更改 制作主
外部“C”
,并可能更改其名称。例如:

 extern "C" int my_main() {
  std::cout << "qwerty" << std::endl;
  return 0;
}
来自
\include的功能
android\u dlopen\u ext
。在上面的代码中,我们传递了一个标志
ANDROID\u DLEXT\u FORCE\u LOAD
,它被记录为:

设置后,不要使用stat(2)检查库是否已加载

当由于某种原因多个ELF文件共享同一文件名时(例如,因为已加载的库已被删除和覆盖),此标志允许强制加载库

请注意,如果库的DT_SONAME与旧库的DT_SONAME相同,并且其他库的DT_NEEDED列表中有该SONAME,则第一个库将用于解析任何依赖项

我认为粗体文本解释了此解决方案的工作原理

3.更改CMakeLists.txt 由于您将动态加载
helloworld\u proto\u lib
,现在可以将其从可执行文件定义中删除,并且不需要任何proto头:

add_executable(avocado
    src/main/cpp/grpc-avocado.cc)

target_link_libraries(avocado
  android
  ${log-lib})
构建、推送和运行 现在,您可以构建、推送可执行文件avocado和两个库libgrpc helloworld.so
libhelloworld\u proto\u lib.so
,然后运行。您不需要
LD\u LIBRARY\u路径
。祝你的项目顺利完成

#include <iostream>
#include <android/dlext.h>
#include <dlfcn.h>

int main() {
  android_dlextinfo extinfo;
  extinfo.flags = ANDROID_DLEXT_FORCE_LOAD;

  void* proto_lib = android_dlopen_ext("/path/to/libhelloworld_proto_lib.so", RTLD_LAZY, &extinfo);
  void* helloworld = dlopen("/path/to/libgrpc-helloworld.so", RTLD_LAZY);
  int (*my_main)() = (int (*)())dlsym(helloworld, "my_main");

  return my_main();
}
add_executable(avocado
    src/main/cpp/grpc-avocado.cc)

target_link_libraries(avocado
  android
  ${log-lib})