将CPP应用程序移植到Android

时间:2014-08-22 11:25:03

标签: java android c++ android-ndk cmake

我需要将CPP项目移植到Android,但由于以下我不确定的事情,我不知所措:

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

  2. 我看到有些人声称他们能够操纵他们的cmake文件和一些自定义android-cmake toolchain,以便从他们的项目中构建他们的“.so”或最终“.apk”。如果没有java包装器可以操作cpp项目的cmake文件来构建项目吗? (来源:Build Android NDK project with Cmake

1 个答案:

答案 0 :(得分:0)

根据我的经验,我会使用android java入口点,否则你很可能遇到问题(你可以制作完整的原生Android应用程序,但我强烈反对它)。

其中一个原因是您需要从CPP内部调用SDK函数,并且使用CPP对Java环境的反射并不是一件容易的事。

步骤如下:

  1. 创建一个非常简单的C代码,它将作为CPP代码的桥梁。以下是我常用的一些示例C函数:
    • OnApplicationStart
    • OnApplicationPaused
    • OnApplicationResumed
    • OnApplicationUpdate
    • OnTouchReceived
  2. 导出这些函数并将它们加载到Java代码中(查找JNI如何执行此操作)
  3. 处理Java中所有特定于Android的操作,以及cpp
  4. 中所有特定于应用程序的操作

    所以你的第一个问题的答案是java包装器不是强制性的,但它是强烈推荐的。

    回答你的第二个问题:

    是的,您可以使用cmkae,ant,cygwin,分配最终创建apk的命令工具(这取决于您感觉如何舒适)。你还是会使用android编译器正在瞄准手臂。

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

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

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

    编辑:

    根据需求,我将简要解释如何处理将CPP应用程序移植到Android的过程:

    1. 使用C入口点重新考虑您的应用程序作为共享库工作:
    2. a。创建一个简单的C应用程序,它将加载你的CPPApp.dll(或者如果你在Linux上的话.so)

      湾在你的.dll中创建最小的必要extern" C"要导出的函数,以便您向dll提供必要的信息

      为简单起见,我们假设我们有3种方法:

       void StartApplication();
       bool OnApplicationUpdate();
       void OnScreenTouched(int x, int y);
      

      ℃。实现简单的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
      2. 一个。将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);
        }
        

        湾在com.sample包中创建java类nativebridge(区分大小写)(您需要尊重名称才能正确链接到本机)

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

        ℃。在本机桥中添加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.so(ndk构建系统,或者你喜欢的任何东西......我会使用ndk,它很容易,只需进入文件夹Android.mk并调用$ ANDROID_NDK_BUILD_PATH / build)

        此时你需要创建一个.mk文件,它将编译你的myCppApp代码,但这超出了范围,你需要自己进行这项研究(一旦你得到它就很简单了)它的悬念)。

        ℃。在您认为合适的任何地方使用Java应用程序中的桥接器中的本机方法。

        一个非常好的提示是通过ndk的hello world样本:

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

        享受。