[英]Porting a CPP application to Android
I need to port a CPP
project to Android
but I somehow got stuck because of the following things that I am not sure of: 我需要将
CPP
项目移植到Android
但是由于以下不确定的原因,我被卡住了:
Do I need to use some kind of java wrapper for my CPP
project at all, ie is it necessarily that I use Android SDK
to integrate my application with Android
? 我的
CPP
项目是否需要使用某种Java包装器,即是否一定要使用Android SDK
将应用程序与Android
集成? If there is another way, which one would that be? 如果还有另一种方法,那将是哪一种?
I have seen some people claiming they have been able to manipulate their cmake file and some custom android-cmake toolchain
to build their “.so”
or eventually an “.apk”
from their project. 我见过有人声称他们已经能够操纵自己的cmake文件和一些自定义的
android-cmake toolchain
来从其项目中构建其“.so”
或最终成为“.apk”
。 Would it be possible without a java
wrapper to manipulate the cmake
files of the cpp project to build your project? 如果没有
java
包装器,是否有可能操纵cpp项目的cmake
文件来构建您的项目? (source: Build Android NDK project with Cmake ) (来源: 使用Cmake构建Android NDK项目 )
From my experience, I would go with using the android java entry point, otherwise you will most likely bump into problems (you can make full native android apps , but I strongly advise against it). 根据我的经验,我会使用android java入口点,否则您很可能会遇到麻烦(您可以制作完整的本机android应用程序,但我强烈建议您这样做)。
One of the reasons is that you will want SDK function calls from inside your CPP, and using reflection on the java environment from CPP isn't trivial. 原因之一是您希望从CPP内部调用SDK函数,并且在CPP上对Java环境进行反射并不是一件容易的事。
The steps would be the following : 步骤如下:
So the answer to your 1st question is that a java wrapper isn't mandatory, but it's HIGHLY recommended. 因此,第一个问题的答案是Java包装器不是必需的,但强烈建议使用。
To answer your 2nd question : 要回答您的第二个问题:
Yes, you can use cmkae, ant, cygwin , allot of command tools that will end up creating your apk (It's up to you on how you feel comfortable).You will still use the android compiler since you are targeting arm. 是的,您可以使用cmkae,ant,cygwin,命令工具分配,这些命令工具最终将创建apk(取决于您的舒适程度)。由于您的目标是arm,因此您仍将使用android编译器。
The difference is that you need to change in your manifest.xml the entry point of the application from a normal activity to a native activity ( http://developer.android.com/reference/android/app/NativeActivity.html ) . 区别在于,您需要在manifest.xml中将应用程序的入口点从正常活动更改为本地活动( http://developer.android.com/reference/android/app/NativeActivity.html )。
As you can see, the difference isn't the build system, it's the way you define your entry point. 如您所见,差异不是构建系统,而是定义入口点的方式。
As a friendly advice, try using the minimal java wrapper approach. 作为友好的建议,请尝试使用最少的Java包装器方法。 You might get to better results sooner, and it won't take you more then 1 week of research on the web on how to link java code to cpp.
您可能会更快地获得更好的结果,并且在Web上花了不到1周的时间进行有关如何将Java代码链接到cpp的研究。
EDIT : 编辑:
As of demand, I will shortly explain how I would approach the process of porting a CPP application to Android : 根据需求,我将简要说明如何将CPP应用程序移植到Android的过程:
a.Create a simple C application that will load yourCPPApp.dll (or .so if you are on linux) 创建一个简单的C应用程序,该应用程序将加载yourCPPApp.dll(如果在Linux上则为.so)
b. 湾 In your .dll create the minimum necessary extern "C" functions to be exported in order for you to give the necessary information to your dll
在您的.dll中,创建要导出的最小必需的extern“ C”函数,以便为您的dll提供必要的信息
For simplicity, we'll assume we have 3 methods : 为了简单起见,我们假设我们有3种方法:
void StartApplication();
bool OnApplicationUpdate();
void OnScreenTouched(int x, int y);
c. C。 Implement the simple C project that will make the calls to these methods externaly (so the .exe will call the methods from the .dll ! )
实现一个简单的C项目,该项目将在外部调用这些方法(因此.exe将从.dll调用这些方法!)
Sample code : 样例代码:
#include "myCPPapp.h"
int main(int arg, char** argv)
{
StartApplication();
srand(time(NULL));
while (OnApplicationUpdate())
{
// we assume we have a 480x640 resolution
OnScreenTouched(rand()%480,rand()%640);
}
return 0;
}
a. 一种。 Rename the exposed methods from myCppApp into java compatible prototypes
将myCppApp中公开的方法重命名为Java兼容的原型
extern "C" {
JNIEXPORT void JNICALL Java_com_sample_nativebridge_OnApplicationStart(JNIEnv env, jobject thiz);
JNIEXPORT jboolean JNICALL Java_com_sample_nativebridge_OnApplcationUpdate(JNIEnv env, jobject thiz);
JNIEXPORT void JNICALL Java_com_sample_nativebridge_OnScreenTouched(JNIEnv env, jobject thiz, jint x, jint y);
}
b. 湾 create the java class nativebridge (case sensitive) in the package com.sample (you need t respect the names in order for correct linkage to native)
在com.sample包中创建java类nativebridge(区分大小写)(您无需尊重名称即可正确链接到native)
class nativebridge {
public static native void OnApplicationStart();
public static native boolean OnApplicationUpdate();
public static native void OnScreenTouched(int x, int y);
}
c. C。 add the load library statement in the native bridge in order to have your library loaded at runtime
在本机桥中添加加载库语句,以便在运行时加载您的库
class nativebridge {
....
static {
System.loadLibrary("myCppApp");
// notice that the lib prefix and .so sufix aren't part of the name
}
}
d. d。 compile your CPP code with the armeabi compiler and create libmyCPPApp.so (ndk build system , or whatever you'd like... i would go with the ndk, it's quite easy , just go into the folder with Android.mk and call $ANDROID_NDK_BUILD_PATH/build )
使用armeabi编译器编译CPP代码并创建libmyCPPApp.so(ndk构建系统,或者您想要的任何东西...我会使用ndk,这很容易,只需使用Android.mk进入文件夹并调用$ ANDROID_NDK_BUILD_PATH / build)
At this point you will need to createa a .mk file that will compile your myCppApp code, but this is out of scope, you will need to do this research on your own (it's quite trivial once you get the hang of it). 此时,您将需要创建一个.mk文件,该文件将编译myCppApp代码,但是这超出了范围,您将需要自己进行这项研究(一旦掌握了它,这很简单)。
c. C。 use the native methods from the bridge inside your java app wherever you see fit.
在您认为合适的地方,使用Java应用程序内部桥中的本机方法。
A very good tip would be to go through a hello world sample of ndk : 一个很好的技巧是遍历ndk的世界示例:
http://www.ntu.edu.sg/home/ehchua/programming/android/android_ndk.html http://www.ntu.edu.sg/home/ehchua/programming/android/android_ndk.html
Enjoy. 请享用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.