facebook twitter hatena line email

Cocos2dx/AndroidNative連携/引数&戻り値あり

提供: 初心者エンジニアの簡易メモ
2017年4月11日 (火) 10:10時点におけるAdmin (トーク | 投稿記録)による版 (Admin がページ「Cocos2dx/AndroidNative実行/引数&戻り値あり」を「Cocos2dx/AndroidNative連携/引数&戻り値あり」に、リダイレクトを残さずに移動しました)

(差分) ←前の版 | 最新版 (差分) | 次の版→ (差分)
移動: 案内検索

サンプルコード

-Classes/NativeLauncher.h

#ifndef Helloworld_NativeLauncher_h
#define Helloworld_NativeLauncher_h
extern "C" {
    class NativeLauncher
    {
    public:
        static void launchNative(); // 引数なし&戻り値なし
        static int tasizanNative(int value, int value2); // 引数数字&戻り値数字
        static const char* getTerminalIdNative(); // 引数なし&戻り値文字列
        static const char* concatNative(const char* str, const char* str2); // 引数文字列&戻り値文字列
        static bool isShow(int); // 引数数字&戻り値bool
    };
}
#endif

-Classes/NativeLauncher.cpp

#include "NativeLauncher.h"
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#define CLASS_NAME "org/cocos2dx/cpp/AppActivity"
extern "C" {
    void NativeLauncher::launchNative()
    {
        cocos2d::JniMethodInfo t;
        if (cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "launchNative", "()V")) {
            t.env->CallStaticVoidMethod(t.classID, t.methodID);
            t.env->DeleteLocalRef(t.classID);
        }
    }
    int NativeLauncher::tasizanNative(int value, int value2)
    {
        int ret = 0;
        cocos2d::JniMethodInfo t;
        if (cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "tasizanNative", "(II)I")) {
            ret = t.env->CallStaticIntMethod(t.classID, t.methodID, value, value2);
            t.env->DeleteLocalRef(t.classID);
        }
        return ret;
    }
    const char* NativeLauncher::getTerminalIdNative()
    {
        cocos2d::JniMethodInfo t;
        if (!cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "getTerminalIdNative", "()Ljava/lang/String;")) {
            return "";
        }
        jstring jpath = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);
        const char* ret = t.env->GetStringUTFChars(jpath, NULL);
        t.env->DeleteLocalRef(jpath);
        t.env->DeleteLocalRef(t.classID);
        return ret;
    }
   const char* NativeLauncher::concatNative(const char* str, const char* str2)
   {
       cocos2d::JniMethodInfo t;
       if (!cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "concatNative", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;")) {
           return "";
       }
       jstring jstr = t.env->NewStringUTF(str);
       jstring jstr2 = t.env->NewStringUTF(str2);
       jstring jpath = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID, jstr, jstr2);
       const char* ret = t.env->GetStringUTFChars(jpath, NULL);
       t.env->DeleteLocalRef(jpath);
       t.env->DeleteLocalRef(t.classID);
       return ret;
   }
   bool NativeLauncher::isShow(int value)
   {
       int ret = 0;
       cocos2d::JniMethodInfo t;
       if (cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "isShow", "(I)Z")) {
           ret = t.env->CallStaticBooleanMethod(t.classID, t.methodID, value);
           t.env->DeleteLocalRef(t.classID);
       }
       return ret;
   }
}

-Classes/HelloWorldScene.h

class HelloWorld : public cocos2d::Layer
{
public:
    static cocos2d::Scene* createScene();
    virtual bool init();
    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);
    void menuLogCallback(cocos2d::Ref* pSender);
    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
};

-Classes/HelloWorldScene.cpp

#include "NativeLauncher.h"
bool HelloWorld::init()
{
// 略
   auto logItem = MenuItemImage::create(
                                          "CloseNormal.png",
                                          "CloseSelected.png",
                                          CC_CALLBACK_1(HelloWorld::menuLogCallback, this));
   logItem->setPosition(Vec2(origin.x + visibleSize.width - logItem->getContentSize().width/2 ,
                                origin.y + visibleSize.height - logItem->getContentSize().height/2));
   auto logmenu = Menu::create(logItem, NULL);
   logmenu->setPosition(Vec2::ZERO);
   this->addChild(logmenu, 1);
// 略
}
void HelloWorld::menuLogCallback(Ref* pSender)
{
    NativeLauncher::launchNative();
    int value = NativeLauncher::tasizanNative(10, 5);
    log("tasizan=%i", value); // tasizan=15
    const char* terminal = NativeLauncher::getTerminalIdNative();
    log("terminalId=%s", terminal); // terminalId=aiudo1234
    const char* str = NativeLauncher::concatNative("abc", "def");
    log("concat=%s", str); // concat=abcdefbool
    bool flag = NativeLauncher::isShow(10);
    log("flag=%i", flag); // 0 or 1
}

-proj.android-studio/app/src/org/cocos2dx/cpp/AppActivity.java

public class AppActivity extends Cocos2dxActivity {
    public static void launchNative()
    {
        System.out.println("launchNative()");
    }
    public static int tasizanNative(int value, int value2)
    {
        System.out.println("tasizan=" + (value + value2));
        return value + value2;
    }
    public static String getTerminalIdNative()
    {
        return "aiueo1234";
    }
    public static String concatNative(String str, String str2)
    {
        System.out.println("concat=" + (str + str2));
        return str + str2;
    }
    public static boolean isShow(int value)
    {
        boolean ret = true;
        if (value > 20) ret = false;
        System.out.println("isShow=" + ret);
        return ret;
    }
}

-proj.android/jni/Android.mk

LOCAL_SRC_FILES := hellocpp/main.cpp \
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/HelloWorldScene.cpp \
                   ../../Classes/NativeLauncher.cpp

NativeLauncher.cppを追加

-proj.android-studio/app/jni/Android.mk

LOCAL_SRC_FILES := hellocpp/main.cpp \
                   ../../../Classes/AppDelegate.cpp \
                   ../../../Classes/HelloWorldScene.cpp \
                   ../../../Classes/NativeLauncher.cpp

NativeLauncher.cppを追加

E/JniHelper: Failed to find static method id ofエラーが出る場合

  • 引数がintの場合は"()V"の部分を"(I)V"に書き換えてあげる
  • 引数がintで戻りもintの場合は"()V"の部分を"(I)I"に書き換えてあげる
  • 引数が2つあり両方intの場合は"()V"の部分を"(II)I"に書き換えてあげる

参考:http://qiita.com/isaoeka/items/9cabb349cd18319fd239

  • 文字列が引数の場合は"()V"の部分に;があるか確認する
if(JniHelper::getStaticMethodInfo(t, CLASS_NAME, "function_name", "( Ljava/lang/String; Ljava/lang/String;)V")

参考:http://r2274.blog9.fc2.com/blog-entry-1658.html

参考:http://discuss.cocos2d-x.org/t/using-jni-with-more-than-one-parameter/3419

warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]エラーが出る場合

char*をconst char*へ変更する