将CPP应用程序移植到Android

Porting a CPP application to Android

本文关键字:Android CPP 应用程序      更新时间:2023-10-16

我需要将CPP项目移植到Android,但我不知何故被卡住了,因为以下事情我不确定:

  1. 我是否需要为我的CPP项目使用某种java包装器,即我是否必须使用Android SDK将我的应用程序与Android集成?如果还有别的办法,那会是哪一种?

  2. 我看到一些人声称他们已经能够操纵他们的cmake文件和一些自定义android-cmake toolchain来构建他们的“.so”或最终从他们的项目中创建“.apk”。如果没有java包装器,是否有可能操作cpp项目的cmake文件来构建您的项目?

根据我的经验,我会使用android java入口点,否则你很可能会遇到问题(你可以制作完整的本机android应用程序,但我强烈建议不要这样做)。

其中一个原因是您希望从CPP内部调用SDK函数,并且从CPP在java环境中使用反射不是微不足道的。

步骤如下:

    创建一个非常简单的C代码,将服务器作为桥梁到您的CPP代码。下面是一些我常用的C函数示例:
    • OnApplicationStart
    • OnApplicationPaused
    • OnApplicationResumed
    • OnApplicationUpdate
    • OnTouchReceived
  1. 导出这些函数并在Java代码中加载它们(查找JNI关于如何做到这一点)
  2. 在Java中处理所有android特定的操作,在cpp中处理所有应用程序特定的操作

所以你的第一个问题的答案是java包装器不是强制性的,但强烈建议使用。

回答你的第二个问题:

是的,你可以使用cmkae, ant, cygwin,很多命令工具来创建你的apk(这取决于你自己的感觉)。你仍然会使用android编译器,因为你的目标是arm。

不同之处在于您需要在manifest.xml中将应用程序的入口点从普通活动更改为本机活动(http://developer.android.com/reference/android/app/NativeActivity.html)。

正如您所看到的,不同之处不在于构建系统,而在于您定义入口点的方式。

作为一个友好的建议,尝试使用最小的java包装器方法。你可能会很快得到更好的结果,而且它不会花你超过1周的时间在网上研究如何将java代码链接到cpp。

编辑:

根据需要,我将简要说明如何将CPP应用程序移植到Android:

  1. 重新考虑你的应用程序作为一个共享库,使用C入口点:

。创建一个简单的C应用程序来加载你的cppapp .dll(如果你在linux上是。so)

b。在你的。dll中创建最小必要的外部"C"函数,以便你给你的dll提供必要的信息

为简单起见,我们假设有3个方法:
 void StartApplication();
 bool OnApplicationUpdate();
 void OnScreenTouched(int x, int y);

c。实现将从外部调用这些方法的简单C项目(因此.exe将从.dll调用这些方法!)

示例代码:
 #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;
 }
  1. 现在我们已经有了完全本机的。exe和。dll,是时候让它与。apk和。so一起工作了

。将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。在包com中创建Java类nativebridge(区分大小写)。示例(为了正确链接到本机,您需要尊重名称)

class nativebridge {
    public static native void OnApplicationStart();
    public static native boolean OnApplicationUpdate();
    public static native void OnScreenTouched(int x, int y);
}

c。在本地桥中添加load library语句,以便在运行时加载库

class nativebridge {
  ....
  static {
    System.loadLibrary("myCppApp"); 
    // notice that the lib prefix and .so sufix aren't part of the name
  }
}

d。使用armeabi编译器编译CPP代码并创建libmyCPPApp。所以(ndk构建系统,或任何你喜欢的…我会使用ndk,它很简单,只要进入Android文件夹。$ANDROID_NDK_BUILD_PATH/build)

在这一点上,你需要创建一个.mk文件来编译你的myCppApp代码,但这超出了范围,你需要自己做这个研究(一旦你掌握了它的技巧,这是相当微不足道的)。

c。在您的Java应用程序中,在您认为合适的地方使用桥中的本机方法。

一个很好的提示是通过一个hello world示例ndk:

http://www.ntu.edu.sg/home/ehchua/programming/android/android_ndk.html