رفتن به مطلب

شروع برنامه نویسی JNI در بی فور


امین مهدی نژاد

ارسال‌های توصیه شده

در این آموزش فقط نحوه ساخت یک کتابخونه JNI - نحوه استفاده از اون و روش تبادل داده بین بیسیک و C++ رو آموزش میدیم.
خب ابتدا میریم سمت C++

فایل هایی که در این قسمت وجود دارند با توضیحات می گم

Application.mk

هر ماژول JNI یک فایل با این نام داره که برخی از تنظیمات کامپایل رو مشخص می کنه. مثلا در کد زیر تعین کردیم که برای انواع دستگاه ها خروجی مناسب تهیه کنه

APP_ABI := all

نکته ای که باید بدونید اینه که JNI با سخت افزار تعامل بیشتری از جاوا داره و به همین دلیل مثلا اگه شما خروجی رو برای CPU های مدل arm بگیرید در cpu های مدل x86 عمل نخواهد کرد. به همین دلیل سعی کنید خروجی مناسب رو تهیه کنید.

Android.mk

از این مدل فایل هم ممکنه یک یا جند تا در پروژتون استفاده کنید.معمولا برای تنظیمات خاصی برای کامپایلر مثلا مشخص کردن فایل های لازم جهت کامپایل به کار میره مثلا:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := mycpp
LOCAL_SRC_FILES := main.cpp

include $(BUILD_SHARED_LIBRARY)

در کد بالا نام ماژول mycpp و فایل کامپایل شونده main.cpp تعین شده

main.h

فایل های هدر معمولا حاوی کدها یا نسخه‌های اجرایی کلاس‌ها (مجموعه متغیرها و توابع) می‌باشند که در بدنه اصلی برنامه از آنها استفاده می‌شود.در اینجا ما هم یکی فایل هدر با نام main.h تهیه کردیم که تنها تابع فعلی ماژول ما رو مشخص کرده

#include <jni.h>

#ifndef _mycpp
#define _mycpp
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jstring JNICALL Java_b4a_example_main_method1
  (JNIEnv *, jobject,jstring);

#ifdef __cplusplus
}
#endif
#endif

در ضمن هدر jni.h رو هم که برای ادامه کار لازم داریم در این فایل اونو افزودیم.

main.cpp

خب بریم سراغ فایل اصلیمون که فعلا کد زیادی در اون قرار ندادیم

#include "main.h"
JNIEXPORT jstring JNICALL Java_b4a_example_main_method1(JNIEnv* pEnv, jobject pThis,jstring str)
{ 
	return pEnv->NewStringUTF("answercenter.ir");
}

اولین نکته و مهمترین نکته ساختار اسم تابع بالاست که حاوی نام پکیج - نام کلاس و نام متد متناظر خودش در کدهای جاوامون می باشه

Java_b4a_example_main_method1

در نام بالا نام پکیج   b4a.example  نام کلاس main و نام متد method1 می باشه.

کلا تابع بال یه متن از کد جاوا می گیره و یه متن به کدهای جاوا بر می گردونه.

به نوع داده ها دقت کنید مثلا jstring از اونجایی که cpp دارای انواع متفاوت تری نسبت به جاوا است این مقادیر در jni  اضافه شده اند تا سازگاری بیشتر بشه.

---------------------------------------------------------------------------------------------

حالا نوبت کامپایل این کتابخونه است

من برای شما دو تا فایل batch نوشتم که با یه دابل کلیک کردن روی هر کدوم نصف کار کامپایل رو انجام بده

compile.bat

این فایل کدهای C++ رو کامپایل می کنه

to jar.bat

این هم اونو تبدیل به فایل JAR می کنه تا بتونید راحت در بی فور از اون استفاده کنید.

--------------------------------------------------------------------------------------------------

بریم سمت بیسیک

ابتدا بهتره آخرین نسخه بی فور رو تهیه کنید تا به مشکل بر نخورید. چون با نسخه های قدیمی زیاد سازگار نیست.

ما اعلام کرده بودیم که در پکیج   b4a.example  و کلاس main و متدی به نام method1 وجود داره. که حالا باید اونو بنویسیم

public native String method1(String str);

خب به عبارت NATIVE دقت کنید چون اینجا لازمه اونو بنویسید.

در ضمن در تابع متناظر CPP ما سه تا آرگومان داشتیم. ولی اینجا فقط یکی نوشتیم. دلیلش هم اونه که در چنین توابعی دو آرگومان اول پیشفرض هستند و نباید در نسخه جاوا اونها رو بنویسیم.

حالا یه چیز دیگه مونده اونم فراخوانی ماژول CPP در جاواست

static {
        System.loadLibrary("mycpp");
		}

تموم حالا می تونیم از کدهای CPP در جاوا استفاده کنیم

	Dim jo As JavaObject
	jo.InitializeContext
	Dim o(1) As Object
	o(0)="Hello"	
	ToastMessageShow(jo.RunMethod("method1",o),True)

چقد طولانی شد.:shok:

NDK رو مطابق لینک زیر دانلود و نصب کنید

دانلود مثال

«موفق باشید.»

لینک ارسال
به اشتراک گذاری در سایت های دیگر

  • 2 هفته بعد...

APP_ABI و APP_PLATFORM در Application.mk

هماهنگ کردن کدهای JNI با سخت افزار و ورژن اندروید در فایل Application.mk صورت می گیرد که به صورت زیر می باشند

  APP_ABI

ارتباط مستقیم کدهای CPP به سخت افزار بخصوص CPU سبب میشه که برای هماهنگی و درست عمل کردن کدها بر اساس نوع CPU خروجی های متفاوتی تهیه کنیم. به عنوان مثال:

APP_ABI := armeabi armeabi-v7a x86 mips arm64-v8a x86_64 mips64

که به صورت پیشفرض armeabi به عنوان نوع خروجی در نظر گرفته می شود. که موارد زیر رو می توانیم برای اون مشخص کنیم

نوع مقدار
ARMv7 APP_ABI := armeabi-v7a
ARMv8 AArch64 APP_ABI := arm64-v8a
IA-32 APP_ABI := x86
Intel64 APP_ABI := x86_64
MIPS32 APP_ABI := mips
MIPS64 (r6) APP_ABI := mips64

همه موارد

APP_ABI := all

نکته:در زمانی که اندازه ماژول بالا باشه داشتن چندین خروجی باعث افزایش سایز برنامه میشه که در این موارد بهتره نوع 64 از هر مدل رو حذف کنیم تا حجم پایین تر بیاد. اگر همچنان سایز نامناسب بود باید نسخه های متنوعی از برنامه انتشار دهیم و یا برای برنامه دیتا بسازیم.تا نسخه مناسب بعد از نصب برنامه دانلود بشه.

APP_PLATFORM

انتخاب نسخه پایه اندروید هم از مواردیست که در بسیاری از مواقع باید اون رو مشخص کنیم که به صورت زیر تنظیم می شود

APP_PLATFORM :=android-9

در جدول زیر شماره اندوید و نسخه اون در NDK مشخص شده

شماره API نسخه اندروید
3 1.5
4 1.6
5 2.0
8 2.2
9 2.3  و 3.0.x
12 3.1.x
13 3.2
14  4.0  و 4.0.2
15 4.0.3  و 4.0.4
16 4.1 و 4.1.1
17  4.2  و 4.2.2 
18 4.3
19 4.4
21 4.4W و  5.0

با وجود متفاوت بودن CPP و جاوا چرا باید نسخه اندروید رو مشخص کنیم؟

خب در JNI می تونیم به API پایه اندروید هم دسترسی داشته باشیم و همچنین خود JNI سعی کرده یک هماهنگی بین انواع داده جاوا و CPP فراهم کنه. و به همین دلایل مشخص نبودن نسخه اندروید احتمال برخورد به مشکل رو برای ما فراهم می کنه.


«موفق باشید.»

   
   
   
   
   
   
   
   
لینک ارسال
به اشتراک گذاری در سایت های دیگر

بایگانی شده

این موضوع بایگانی و قفل شده و دیگر امکان ارسال پاسخ نیست.

  • کاربران آنلاین در این صفحه   0 کاربر

    • هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.
×
×
  • اضافه کردن...