我如何准备我的.cpp文件以便Android ndk构建它们?[英] How do I prepare my .cpp files for the Android ndk to build them?

本文是小编为大家收集整理的关于我如何准备我的.cpp文件以便Android ndk构建它们?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我们目前有一些用C ++编写的图像处理软件,该软件正在我们的iOS应用程序使用.我正在尝试将此图像处理代码集成到我使用Android NDK创建的Android项目中.

我有我的Android项目和SDK所有设置并准备就绪.我也有NDK设置并准备好了.

我在 tutorial (这很棒),很棒),我对他为本机定义了代码的部分感到困惑.C,因为它具有这样的函数名称,

void Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_helloLog(JNIEnv * env, jobject this, jstring logThis) 

在我看来,我必须浏览所有现有的C ++功能并更改代码以使NDK识别它.

所以这是我的问题,

  1. 我是否必须更改现有的C ++代码才能与NDK构建器一起使用?如果是这样,我需要更改这项工作的代码?
  2. 有没有办法让android.mk文件构建整个目录?我有很多文件,我不想列出每个文件才能建立它们.

推荐答案

1)您应该能够构建而无需更改,但是您需要编写一些JNI包装器功能才能从Java调用它.希望您有少量的顶级课程,只需要包装这些课程即可.例如.这是我(慢慢)写作的游戏:

// android.cpp
#include "game.h"
#include <jni.h>

namespace {
    Game* toGame(jlong gamePtr) {
        return reinterpret_cast<Game*>(gamePtr);
    }
}

extern "C" {

    jlong Java_com_rarepebble_game3_Game_create(JNIEnv* env, jobject jobj) {
        Game* g = new Game();
        return reinterpret_cast<jlong>(g);
    }

    void Java_com_rarepebble_game3_Game_destroy(JNIEnv* env, jobject jobj, jlong gamePtr) {
        delete toGame(gamePtr);
    }

    void Java_com_rarepebble_game3_Game_update(JNIEnv* env, jobject jobj, jlong gamePtr, jboolean isTouching, jfloat touchX, jfloat touchY) {
        toGame(gamePtr)->update(isTouching, touchX, touchY);
    }

    void Java_com_rarepebble_game3_Game_render(JNIEnv* env, jobject jobj, jlong gamePtr) {
        toGame(gamePtr)->render();
    }

    // ... and a few others. Only one class, though.
}

在爪哇一侧,这让我可以在我的com.rarepebble.game3.Game类中声明这些功能,并在应用程序生命周期中的适当时间打电话给它们. (请注意Java软件包,类和功能名称与C ++中的函数名称相对应):

//Game.java
package com.rarepebble.game3;

// (imports)

public class Game {
    static {
        System.loadLibrary("game3lib");
    }
    // These are the functions you defined in C++
    private native long create();
    private native void destroy(long gamePtr);    
    private native void update(long gamePtr, boolean isTouched, float x, float y);
    private native void render(long gamePtr);

    private long gamePtr = 0;

    Game() {
        gamePtr = create();
    }

    @Override
    protected void finalize() throws Throwable {
        if (gamePtr != 0) {
            destroy(gamePtr);
        }
        super.finalize();
    }

    // etc...
}

2)您可以使用

local_src_files:= $(Wildcard *.cpp)$(Wildcard subdirectory/*.cpp)#etc ...

编辑:根据要求,我的C ++游戏类标题" game.h":

// game.h
#ifndef GAME_INCLUDED
#define GAME_INCLUDED

// Various game and standard library includes.
// *NO* JNI or Android includes.

namespace game {

    class Game {
    public:
        Game();
        ~Game();

        void update(bool isTouching, float touchX, float touchY);
        void render();

        // other funcs...

    private:
        // etc...
    };

}

#endif //def GAME_INCLUDED  

类似地," game.cpp"也不包含任何JNI的东西.

本文地址:https://www.itbaoku.cn/post/102669.html

问题描述

We currently have some image processing software written in c++ which is being used by our IOS application. I am trying to integrate this image processing code into the android project that I created using the Android NDK.

I have my android project and the sdk all setup and ready to go. I also have the ndk setup and ready to go.

I was following through on this tutorial (which is awesome), and I got stumped at the part that he defined the code for native.c because it had a function name like this,

void Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_helloLog(JNIEnv * env, jobject this, jstring logThis) 

It almost looks to me like I have to go through all of my existing c++ functions and alter the code in order for the NDK to recognize it.

So here are my questions,

  1. Do I have to alter my existing c++ code in order for it to work with the ndk builder? And if so, what are the things I need to change in my code for this work?
  2. Is there a way to have the Android.mk file build an entire directory? I have a lot of files and I did not want to have to list out every single one of them in order to get them built.

推荐答案

1) You should be able to build without alteration, but you will need to write some of those JNI wrapper functions to call it from Java. Hopefully you have a small number of top-level classes and you will only need to wrap those. E.g. Here's what I have for a game I'm (slowly) writing:

// android.cpp
#include "game.h"
#include <jni.h>

namespace {
    Game* toGame(jlong gamePtr) {
        return reinterpret_cast<Game*>(gamePtr);
    }
}

extern "C" {

    jlong Java_com_rarepebble_game3_Game_create(JNIEnv* env, jobject jobj) {
        Game* g = new Game();
        return reinterpret_cast<jlong>(g);
    }

    void Java_com_rarepebble_game3_Game_destroy(JNIEnv* env, jobject jobj, jlong gamePtr) {
        delete toGame(gamePtr);
    }

    void Java_com_rarepebble_game3_Game_update(JNIEnv* env, jobject jobj, jlong gamePtr, jboolean isTouching, jfloat touchX, jfloat touchY) {
        toGame(gamePtr)->update(isTouching, touchX, touchY);
    }

    void Java_com_rarepebble_game3_Game_render(JNIEnv* env, jobject jobj, jlong gamePtr) {
        toGame(gamePtr)->render();
    }

    // ... and a few others. Only one class, though.
}

On the Java side this lets me declare those functions in my com.rarepebble.game3.Game class and call them at the appropriate times in the app's lifecycle. (Note how the Java package, class and function names correspond to the function names in C++):

//Game.java
package com.rarepebble.game3;

// (imports)

public class Game {
    static {
        System.loadLibrary("game3lib");
    }
    // These are the functions you defined in C++
    private native long create();
    private native void destroy(long gamePtr);    
    private native void update(long gamePtr, boolean isTouched, float x, float y);
    private native void render(long gamePtr);

    private long gamePtr = 0;

    Game() {
        gamePtr = create();
    }

    @Override
    protected void finalize() throws Throwable {
        if (gamePtr != 0) {
            destroy(gamePtr);
        }
        super.finalize();
    }

    // etc...
}

2) You can use

LOCAL_SRC_FILES := $(wildcard *.cpp) $(wildcard subdirectory/*.cpp) #etc...

Edit: As requested, my C++ Game class header, "game.h":

// game.h
#ifndef GAME_INCLUDED
#define GAME_INCLUDED

// Various game and standard library includes.
// *NO* JNI or Android includes.

namespace game {

    class Game {
    public:
        Game();
        ~Game();

        void update(bool isTouching, float touchX, float touchY);
        void render();

        // other funcs...

    private:
        // etc...
    };

}

#endif //def GAME_INCLUDED  

Similarly, "game.cpp" doesn't include any JNI stuff either.