facebook twitter hatena line email

「Cocos2dx/AndroidNative連携/引数&戻り値あり」の版間の差分

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
(Admin がページ「Cocos2dx/AndroidNative実行/引数&戻り値あり」を「Cocos2dx/AndroidNative連携/引数&戻り値あり」に、リダイレクトを残さずに移動しました)
 
(同じ利用者による、間の15版が非表示)
行3: 行3:
 
  #ifndef Helloworld_NativeLauncher_h
 
  #ifndef Helloworld_NativeLauncher_h
 
  #define Helloworld_NativeLauncher_h
 
  #define Helloworld_NativeLauncher_h
  class NativeLauncher
+
  extern "C" {
{
+
    class NativeLauncher
public:
+
    {
    static void launchNative();
+
    public:
public:
+
        static void launchNative(); // 引数なし&戻り値なし
    static int tasizan(int value, int value2);
+
        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
 
  #endif
  
行17: 行21:
 
  #include "platform/android/jni/JniHelper.h"
 
  #include "platform/android/jni/JniHelper.h"
 
  #define CLASS_NAME "org/cocos2dx/cpp/AppActivity"
 
  #define CLASS_NAME "org/cocos2dx/cpp/AppActivity"
  void NativeLauncher::launchNative()
+
  extern "C" {
{
+
    void NativeLauncher::launchNative()
    cocos2d::JniMethodInfo t;
+
    {
    if (cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "launchNative", "()V")) {
+
        cocos2d::JniMethodInfo t;
        t.env->CallStaticVoidMethod(t.classID, t.methodID);
+
        if (cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "launchNative", "()V")) {
        t.env->DeleteLocalRef(t.classID);
+
            t.env->CallStaticVoidMethod(t.classID, t.methodID);
 +
            t.env->DeleteLocalRef(t.classID);
 +
        }
 
     }
 
     }
}
+
    int NativeLauncher::tasizanNative(int value, int value2)
int NativeLauncher::tasizan(int value, int value2)
+
    {
{
+
        int ret = 0;
    int ret = 0;
+
        cocos2d::JniMethodInfo t;
    cocos2d::JniMethodInfo t;
+
        if (cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "tasizanNative", "(II)I")) {
    if (cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "tasizan", "(II)I")) {
+
            ret = t.env->CallStaticIntMethod(t.classID, t.methodID, value, value2);
        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);
 
         t.env->DeleteLocalRef(t.classID);
 +
        return ret;
 
     }
 
     }
    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;
 +
    }
 
  }
 
  }
  
行68: 行110:
 
  {
 
  {
 
     NativeLauncher::launchNative();
 
     NativeLauncher::launchNative();
     int value = NativeLauncher::tasizan(10, 5);
+
     int value = NativeLauncher::tasizanNative(10, 5);
     log("tasizan=%i", value);
+
     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
 
  }
 
  }
  
行78: 行126:
 
         System.out.println("launchNative()");
 
         System.out.println("launchNative()");
 
     }
 
     }
     public static int tasizan(int value, int value2)
+
     public static int tasizanNative(int value, int value2)
 
     {
 
     {
 
         System.out.println("tasizan=" + (value + value2));
 
         System.out.println("tasizan=" + (value + value2));
 
         return 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;
 
     }
 
     }
 
  }
 
  }
行92: 行156:
 
NativeLauncher.cppを追加
 
NativeLauncher.cppを追加
  
-proj.android-studio/jni/Android.mk
+
-proj.android-studio/app/jni/Android.mk
 
  LOCAL_SRC_FILES := hellocpp/main.cpp \
 
  LOCAL_SRC_FILES := hellocpp/main.cpp \
                     ../../Classes/AppDelegate.cpp \
+
                     ../../../Classes/AppDelegate.cpp \
                     ../../Classes/HelloWorldScene.cpp \
+
                     ../../../Classes/HelloWorldScene.cpp \
                     ../../Classes/NativeLauncher.cpp
+
                     ../../../Classes/NativeLauncher.cpp
 
NativeLauncher.cppを追加
 
NativeLauncher.cppを追加
  
行108: 行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*へ変更する