- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我从 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.so
和 libprotobuf-cpp-lite.so
的 protobuf 库版本,看起来他们的版本是 3.0.0。这与我们编译成静态库或共享库的版本 (3.5.1) 冲突。
最佳答案
我不太清楚为什么会这样。关于链接器加载后的事情 helloworld_proto_lib
,它会覆盖所有已加载的 protobuf 符号,并且由于某种原因,另一个与您无关的库会使您的程序崩溃。但这并没有告诉您任何新信息。
下面是解决这个问题的一种方法:
做主extern "C"
,并可能更改其名称。例如:
extern "C" int my_main() {
std::cout << "qwerty" << std::endl;
return 0;
}
这将包含可执行文件的实际主体,它将动态加载库 helloworld_proto_lib
和 grpc-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.
我认为粗体文本解释了为什么这个解决方案有效。
因为您将加载 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/
我已经为我的 Android 应用设置了 Google Play 测试版程序。想象一下以下场景: 我将 apk1 作为 versionCode 1 的测试版发布 Beta 用户安装此 Beta 版本
我需要在 android studio 中生成一个未签名的 APK。我看到了其他一些关于此的问题。 Export unsigned apk from a Gradle Project in Andro
我想知道更新是如何进行的?它如何更新特定文件仅更改?我的意思是在更新期间,整个 apk 是否再次安装或仅特定文件更改?它是如何工作的?我只想知道 android market 如何在没有用户提示的情况
如何在使用新 apk 的情况下升级 android 应用程序而不丢失以前的 apk 数据? 最佳答案 有一个versionCode AndroidManifest.xml 中的元素。这是一个整数,每个
我看到 Android 在输出文件夹中同时创建了一个“普通”APK 和一个 androidTest APK? 即 app-dev-debug.apk app-dev-debug-androidTest
Upload failed You uploaded an APK that is signed with a different certificate to your previous APKs.
对我来说,这发生在所有项目中。当我从 Android Studio 生成签名的 apk 时,我收到以下正确消息: 问题:在此之后,当我实际上并没有生成签名的 apk 时,我继续为项目发生的每个构建收到
我需要在 Windows 上反编译 & 重新编译一个 apk... 我正在关注此链接 Reverse Engineer APK 问题是我找不到发出请求的文件(请参阅上面的链接)“找到发出请求的文件 g
我寻找一种方法来制作一个可以更改我的第一个 apk 的默认图标的 apk。例如 ADW Launcher。 我该怎么做?也许是一种获取另一个 apk 的绘图的方法? 感谢您的帮助。 最佳答案 我想您正
我正在开发一个基于图像的应用程序,具有以下属性: 手机版本的 apk 大小(不含图像)约为 15MB,平板电脑版本约为 25MB。 图像总大小约为 30MB。 该应用程序将以测试版状态发布,可能会频繁
假设在网站上我有一个 apk 和网站的在线 JSON 数据,现在依赖于那个 apk 我想用新的 JSON 数据重新生成新的 apk 文件,还需要Manifest文件中的应用图标也要动态变化,包名也要动
今天我注意到当我在 Eclipse 中导出我的应用程序时,我得到了一个无扩展名的文件。我过去没有注意到这一点,所以我将此文件作为我的应用程序的 APK 文件上传到 Google Play。当我今天看到
我有一个同时适用于手机/平板电脑和电视的应用程序。当我在电视上使用 leanback 时,这个项目由 3 个模块组成。第一个(库)包含电视和移动/平板电脑模块通用的所有类,然后我有电视和移动/平板电脑
我制作了一个仅包含微调器和按钮的基本应用程序,但它的 Release模式大小为 1.4 MB,我认为这太大了,因为也有很多低于 200kB 的好应用程序可用 所以我在 gradle 文件中尝试了 b
我的移动开发人员已向我提供了一个 APK 文件,我需要将其上传到商店。它说,你需要在 Release模式下编译它。有没有一种方法可以让我对 apk 执行此操作,使其进入 Release模式并使用 ke
我在里面制作了一个 android 应用程序,我已经在“res/raw”文件夹中放置了一个 apk 文件,现在我在安装我的 apk 时想要什么,raw 文件夹中的 apk 也会安装,而无需再次单击安装
我有一个带有未签名包的 android 应用程序,每当我尝试安装此 apk 时,都会出现以下错误消息:Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]。 现
我开发的 Android 应用由不同的人群进行测试。 我们使用 Google Play Beta 方案。 同一组测试人员也提供生产支持。完成测试后,他们需要将设备恢复为生产应用,以便反射(reflec
我有一个已发布的应用程序。该应用程序使用 Google 的许可检查,因此为了测试该应用程序的新版本(使用测试帐户),必须在开发者控制台中上传 APK: 对于尚未上传到 Google Play 的应用程
我正在制作一个应用程序,我想在其中调用其他一些 apk(未预装),它们存在于我手机的 SD 卡中,我希望在安装主应用程序时安装它们。这可能吗?以及如何? 最佳答案 您可以使用以下 Intent 请求
我是一名优秀的程序员,十分优秀!