这是我写的一个简单的包装:
#include <android/log.h>
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>
typedef int (*main_t)(int argc, char** argv);
static int help(const char* argv0)
{
printf("%s: simple wrapper to work around LD_LIBRARY_PATH\n\n", argv0);
printf("Args: executable, list all the libraries you need to load in dependency order, executable again, optional parameters\n");
printf("example: %s /data/local/ttte /data/data/app/com.testwrapper/lib/ttt.so /data/local/ttte 12345\n", argv0);
printf("Note: the executable should be built with CFLAGS=\"-fPIC -pie\", LDFLAGS=\"-rdynamic\"\n");
return -1;
}
int main(int argc, char** argv)
{
int rc, nlibs;
void *dl_handle;
if (argc < 2)
{
return help(argv[0]);
}
__android_log_print(ANDROID_LOG_DEBUG, "wrapper", "running '%s'", argv[1]);
for (nlibs = 2; ; nlibs++)
{
if (nlibs >= argc)
{
return help(argv[0]);
}
__android_log_print(ANDROID_LOG_DEBUG, "wrapper", "loading '%s'", argv[nlibs]);
dl_handle = dlopen(argv[nlibs], 0); // do not keep the handle, except for the last
__android_log_print(ANDROID_LOG_DEBUG, "wrapper", "loaded '%s' -> %p", argv[nlibs], dl_handle);
if (strcmp(argv[1], argv[nlibs]) == 0)
{
break;
}
}
main_t pmain = (main_t)dlsym(dl_handle, "main");
__android_log_print(ANDROID_LOG_DEBUG, "wrapper", "found '%s' -> %p", "main", pmain);
rc = pmain(argc - nlibs, argv + nlibs);
// we are exiting the process anyway, don't need to clean the handles actually
// __android_log_print(3, "wrapper", "closing '%s'", argv[1]);
// dlclose(dl_handle);
return 0;
}
为了保持其可读性,我放弃了大部分错误处理、不必要的清理和特殊情况的处理。
Android.mk
对于这个可执行文件:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := wrapper
LOCAL_SRC_FILES := wrapper/main.c
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)
请注意,您必须负责部署:将其打包wrapper
进入 APK,解压到某个本地路径(切勿解压到 USB 存储或解压到/sdcard
!),将其标记为可执行(chmod 777
).
这些是您在构建通过以下方式运行的可执行文件时必须提供的附加参数:wrapper
。如果你使用ndk-build
构建它们,如下所示:
LOCAL_C_FLAGS += -fPIC -pie
LOCAL_LDFLAGS += -rdynamic
请注意,您不需要chmod
不再需要这些可执行文件了。另一个技巧:你可以构建中学可执行文件到共享库中,并且相同的包装器将继续工作!这省去了部署这些二进制文件的麻烦。 NDK 和 Android 构建将通过 APK 的 libs/armeabi 自动将它们安全地传送到应用程序的 lib 目录。
Update
似乎有一个更简单的解决方案,使用流程构建器 http://developer.android.com/reference/java/lang/ProcessBuilder.html修改环境:https://stackoverflow.com/a/8962189/192373 https://stackoverflow.com/a/8962189/192373.