gpt4 book ai didi

android - 构建使用 Protocol Buffer 的 Android 可执行 gRPC 服务器(无 APK)

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:04:56 24 4
gpt4 key购买 nike

我从 here 编译了 gRPC Android 示例.

我想从 adb shell 将程序作为可执行文件运行。

将这些行添加到 grpc-helloworld.cc:

#include <iostream>

int main() {
std::cout << "qwerty" << std::endl;
return 0;
}

CMakeLists.txt 中的这些行:

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

target_include_directories(avocado
PRIVATE ${HELLOWORLD_PROTO_HEADERS})

target_link_libraries(avocado
helloworld_proto_lib
android
${log-lib})

然后我推送生成的可执行文件和 libs 文件并尝试运行它:

LD_LIBRARY_PATH=。 ./鳄梨

我收到以下错误:

[libprotobuf FATAL /home/buga/grpc/third_party/protobuf/src/google/protobuf/stubs/common.cc:79] This program was compiled against version 3.0.0 of the Protocol Buffer runtime library, which is not compatible with the installed version (3.5.1). Contact the program author for an update. If you compiled the program yourself, make sure that your headers are from the same version of Protocol Buffers as your link-time library. (Version verification failed in "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".)terminating with uncaught exception of type google::protobuf::FatalException: This program was compiled against version 3.0.0 of the Protocol Buffer runtime library, which is not compatible with the installed version (3.5.1). Contact the program author for an update. If you compiled the program yourself, make sure that your headers are from the same version of Protocol Buffers as your link-time library. (Version verification failed in "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".) Aborted

我做错了什么?

我们意识到有一个名为 libprotobuf-cpp-full.solibprotobuf-cpp-lite.so 的 protobuf 库版本,看起来他们的版本是 3.0.0。这与我们编译成静态库或共享库的版本 (3.5.1) 冲突。

最佳答案

我不太清楚为什么会这样。关于链接器加载后的事情 helloworld_proto_lib ,它会覆盖所有已加载的 protobuf 符号,并且由于某种原因,另一个与您无关的库会使您的程序崩溃。但这并没有告诉您任何新信息。

下面是解决这个问题的一种方法:

1。 grpc-helloworld.cc 的变化

做主extern "C" ,并可能更改其名称。例如:

 extern "C" int my_main() {
std::cout << "qwerty" << std::endl;
return 0;
}

2。添加文件 grpc-avocado.cc

这将包含可执行文件的实际主体,它将动态加载库 helloworld_proto_libgrpc-helloworld .方法如下:

#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();
}

函数android_dlopen_ext来自 #include <android/dlext.h>及其标志参数在此处进行了描述:https://developer.android.com/ndk/reference/group/libdl .在上面的代码中,我们传递了标志 ANDROID_DLEXT_FORCE_LOAD ,记录为:

When set, do not use stat(2) to check if the library has already been loaded.

This flag allows forced loading of the library in the case when for some reason multiple ELF files share the same filename (because the already-loaded library has been removed and overwritten, for example).

Note that if the library has the same DT_SONAME as an old one and some other library has the soname in its DT_NEEDED list, the first one will be used to resolve any dependencies.

我认为粗体文本解释了为什么这个解决方案有效。

3。更改 CMakeLists.txt

因为您将加载 helloworld_proto_lib动态地,您现在可以将其从可执行文件定义中删除,并且不需要任何原型(prototype) header :

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

target_link_libraries(avocado
android
${log-lib})

构建、推送和运行

您现在可以构建、推送可执行文件 avocado和两个库 libgrpc-helloworld.so , libhelloworld_proto_lib.so , 并运行。你不需要 LD_LIBRARY_PATH .祝你的项目的其余部分好运!

关于android - 构建使用 Protocol Buffer 的 Android 可执行 gRPC 服务器(无 APK),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52203862/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com