فراخوانی توابع java در ++C
احتمالا وقتی دارید یک بازی را با ابزاری با قابلیت چند سکویی مثل cocso2d-x توسعه می دهید پیش خواهد آمد که نیاز داشته باشید که از امکانات اختصاصی یک پلتفرم استفاده کنید .
به عنوان مثال فراخوانی متد مربوط به ثبت نظر و فراخوانی اکتیویتی بازار نمونه خوبی از این نیاز به حساب میاد یا خیلی مثال های دیگری که خود شما حتما هنگام تکمیل کردن بازی با آنها رو به رو خواهید شد.
خب هر وقت که به همچین نیازی برخوردید نیازی به درماندگی نیست اگر بلد باشید که در داخل کد های بازی که با ++C نوشته اید توابع جاوا را فراخوانی کنید .
البته برای این کار باید آشنایی حداقلی با برنامه نویسی جاوا نیز داشته باشید که احتمالا این آشنایی رو دارید پس شروع می کنیم .
با یک مثال ساده شروع می کنیم .در ساده ترین حالت ما یک تابع جاوا بدون مقدار بازگشتی یا ارگومان ورودی داریم .سعی کنید بیشتر کار ها رو به همچین تابع هایی تبدیل کنید :)
چنانچه ما تابعی به اسم doMeAFavour در داخل کلاس MyAwesomeJavaClass داشته باشیم برای فراخوانی آن کافی است که به شکل زیر عمل کنیم .
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t,
"MyAwesomeJavaClass",
"doMeAFavour",
"()V")) {
t.env->CallStaticVoidMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID);
}
برای استفاده از متد های بالا نیاز به بارگذاری JniHelper.h دارید
به همین سادگی ...
اما اگر نیاز به ارسال پارامتر و یا بازگردانی مقادیر باشید نیاز دارید که یکم بیشتر تو نخ جاوا و نحوه فراخوانی توابع بریم .
احتمالا رشته "V()" رو داخل مثال بالا مشاهده کرید و در موردش کنجکاو شدید باید بگم که با این رشته شما نحوه فراخوانی تابع را به سی پلاس پلاس مشخص می کنید و در اصطلاح امضای تابع جاوا به شمار می رود که نشان دهنده نداشتن آرگومان ورودی و void بودن نوع بازگشتی است .
برای شروع یک سری قانون به شرح زیر داریم که باید بهش توجه داشته باشید:
Java Type | Signature |
void | V |
boolean | Z |
byte | B |
char | C |
short | S |
int | I |
long | J |
float | F |
double | D |
fully-qualified-class | L fully-qualified-class ; |
type[] | [ type |
method type | ( arg-types ) ret-type |
مثال :
static String doMeAFavour(int times)
// Signature: "(I;)Ljava/lang/String;"
static bool sayHello(String to, int times)
// Signature: "(Ljava/lang/String;I;)Z;"
ارسال پارامتر و بازگردانی مقدار:
فرض کنید تابعی با مقدار بازگشتی bool و دو آرگومان ورودی داریم
static bool sayHello(String to, int times)
برای فراخوانی آن در سی پلاس پلاسبه صورت زیر عمل می کنیم
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t,
"MyAwesomeJavaClass",
"sayHello",
"(Ljava/lang/String;I;)Z;")) {
const char* myName = "Beautiful Name";
int times = 3;
jstring stringArg1 = t.env->NewStringUTF(myName);
jboolean retV = t.env->CallStaticBooleanMethod(t.classID,
t.methodID,
stringArg1,
times);
t.env->DeleteLocalRef(t.classID);
t.env->DeleteLocalRef(stringArg1);
}
برای تبدیل نوع ها هم می توانید از توابع کلاس JniHelper استفاده کنید به عنوان مثال برای تبدیل نوع Jstring به string به شیوه زیر عمل می شود .
jstring s = (jstring) t.env->CallObjectMethod(t.classID,
t.methodID);
// convert it to std::string
std::string str = JniHelper::jstring2string(s);
به احتمال زیاد کاربرد های خیلی بیشتری برای این تکنیک می تونید در نظر بگیرید :)