「Cocos2dx/AndroidNative連携/引数&戻り値あり」の版間の差分
提供: 初心者エンジニアの簡易メモ
(ページの作成:「 ==E/JniHelper: Failed to find static method id ofエラーが出る場合== *引数がintの場合は"()V"の部分を"(I)V"に書き換えてあげる *引数がintで...」) |
細 (Admin がページ「Cocos2dx/AndroidNative実行/引数&戻り値あり」を「Cocos2dx/AndroidNative連携/引数&戻り値あり」に、リダイレクトを残さずに移動しました) |
||
(同じ利用者による、間の18版が非表示) | |||
行1: | 行1: | ||
+ | ==サンプルコード== | ||
+ | -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エラーが出る場合== | ==E/JniHelper: Failed to find static method id ofエラーが出る場合== | ||
行9: | 行172: | ||
if(JniHelper::getStaticMethodInfo(t, CLASS_NAME, "function_name", "( Ljava/lang/String; Ljava/lang/String;)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://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*へ変更する |
2017年4月11日 (火) 10:10時点における最新版
サンプルコード
-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*へ変更する