الوصول الأصلي لجافا

مكتبة Java Native Access ( JNA ) هي مكتبة برمجية طورتها المجتمعات البرمجية، تُتيح لبرامج Java الوصول بسهولة إلى المكتبات المشتركة الأصلية دون الحاجة إلى استخدام واجهة Java Native Interface (JNI). يهدف تصميم JNA إلى توفير وصول أصلي سلس بأقل جهد ممكن. على عكس JNI، لا تتطلب JNA أي شيفرة نمطية أو شيفرة وسيطة مُولّدة.

منذ إصدار Java 22، تم توفير واجهة برمجة تطبيقات الوظائف الخارجية والذاكرة كبديل قياسي حديث.

بنيان

تستخدم مكتبة JNA مكتبةً أصليةً صغيرةً تُسمى مكتبة واجهة الدوال الخارجية ( libffi ) لاستدعاء التعليمات البرمجية الأصلية ديناميكيًا . تستخدم مكتبة JNA دوالًا أصليةً تُمكّن التعليمات البرمجية من تحميل مكتبة بالاسم واسترجاع مؤشر إلى دالة داخل تلك المكتبة، ثم تستخدم مكتبة libffi لاستدعائها، كل ذلك دون الحاجة إلى روابط ثابتة أو ملفات رأسية أو أي مرحلة تجميع. يستخدم المطور واجهة Java لوصف الدوال والهياكل في المكتبة الأصلية المستهدفة. هذا يُسهّل الاستفادة من ميزات النظام الأساسي الأصلية دون تكبّد عبء التطوير الكبير الناتج عن تهيئة وبناء تعليمات JNI البرمجية.

تم بناء واختبار JNA على أنظمة macOS و Microsoft Windows و FreeBSD / OpenBSD و Solaris و Linux و AIX و Windows Mobile و Android . كما يُمكن تعديل وإعادة تجميع إعدادات البناء الأصلية لجعلها تعمل على معظم المنصات الأخرى التي تُشغّل Java.

أنواع التعيين

يوضح الجدول التالي نظرة عامة على أنواع البيانات التي يتم ربطها بين لغة جافا والبرمجيات الأصلية والتي تدعمها مكتبة JNA. [ 2 ]

النوع الأصليمقاسجافا تايبأنواع ويندوز الشائعة
char،int8_tعدد صحيح مكون من 8 بتbyteBYTE،TCHAR
short،int16_tعدد صحيح مكون من 16 بتshortWORD
wchar_t،char16_tحرف 16/32 بتcharTCHAR
int،int32_tعدد صحيح 32 بتintDWORD
int،boolقيمة منطقيةbooleanBOOL
longعدد صحيح 32/64 بتcom.sun.jna.NativeLongLONG
long long،int64_tعدد صحيح 64 بتlong__int64
float،float32_t32 بت FPfloat
double،float64_t64 بت FPdouble
char*سلسلة Cjava.lang.StringLPCSTR
void*مؤشرcom.sun.jna.PointerLPVOID، HANDLE،LPXXX

ملاحظة: فيما يلي معنى TCHARالتغييرات بين charو wchar_tوفقًا لبعض تعريفات المعالج المسبق.LPCTSTR

محاذاة بايتات الذاكرة لهياكل البيانات

لا تملك المكتبات الأصلية معيارًا موحدًا لمحاذاة بايتات الذاكرة. يعتمد JNA افتراضيًا على إعدادات نظام التشغيل، والتي يمكن تجاوزها بمحاذاة مخصصة خاصة بالمكتبة. إذا لم تُذكر تفاصيل المحاذاة في وثائق المكتبة الأصلية، فيجب تحديد المحاذاة الصحيحة بالتجربة والخطأ أثناء تنفيذ غلاف Java.

مثال

يقوم البرنامج التالي بتحميل تطبيق مكتبة C القياسية المحلية ويستخدمه لاستدعاء دالة printf .

ملاحظة: الكود التالي قابل للنقل ويعمل بنفس الطريقة على أنظمة التشغيل Windows و POSIX ( Linux / Unix / macOS ).

package org.wikipedia.examples ;استيراد com.sun.jna.Library ؛ استيراد com.sun.jna.Native ؛ استيراد com.sun.jna.Platform ؛// مثال بسيط لتعريف واستخدام مكتبة أصلية. public class HelloWorld { public interface CLibrary extends Library { CLibrary INSTANCE = ( CLibrary ) Native . loadLibrary ( ( Platform . isWindows () ? "msvcrt" : "c" ), CLibrary . class ); void printf ( String format , Object ... args ); }public static void main ( String [] args ) { CLibrary . INSTANCE . printf ( "Hello, World\n" ); for ( int i = 0 ; i < args . length ; i ++ ) { CLibrary . INSTANCE . printf ( "Argument %d: %s\n" , i , args [ i ] ); } } }

يقوم البرنامج التالي بتحميل مكتبة C POSIX ويستخدمها لاستدعاء وظيفة mkdir القياسية .

ملاحظة: الكود التالي قابل للنقل ويعمل بنفس الطريقة على منصات معايير POSIX .

package org.wikipedia.examples ;استيراد com.sun.jna.Library ؛ استيراد com.sun.jna.Native ؛// مثال بسيط لتعريف واستخدام مكتبة POSIX الأصلية في لغة C. public class Example { public interface Posix extends Library { public int chmod ( String filename , int mode ); public int chown ( String filename , int user , int group ); public int rename ( String oldpath , String newpath ); public int kill ( int pid , int signal ); public int link ( String oldpath , String newpath ); public int mkdir ( String path , int mode ); public int rmdir ( String path ); }public static void main ( String [] args ) { // من الممكن تحميل مكتبة msvcrt لدعمها الجزئي لمعيار POSIX على نظام ويندوز... Posix posix = ( Posix ) Native . loadLibrary ( "c" , Posix . class ); // ولكن سيظل التحميل يفشل على نظام ويندوز بسبب عدم وجود /tmp. posix . mkdir ( "/tmp/newdir" , 0777 ); posix . rename ( "/tmp/newdir" , "/tmp/renamedir" ); } }

يقوم البرنامج أدناه بتحميل ملف Kernel32.dll ويستخدمه لاستدعاء وظائف Beep و Sleep .

ملاحظة: يعمل الكود التالي فقط على أنظمة ويندوز .

package org.wikipedia.examples ;استيراد com.sun.jna.Library ؛ استيراد com.sun.jna.Native ؛// مثال بسيط لتعريف واستخدام مكتبة أصلية لنظام ويندوز. public class Example { public interface Kernel32 extends Library { // يُعبر عن التردد بالهرتز ويتراوح من 37 إلى 32767 // يُعبر عن المدة بالمللي ثانية public boolean Beep ( int FREQUENCY , int DURATION ); public void Sleep ( int DURATION ); }public static void main ( String [] args ) { Kernel32 lib = ( Kernel32 ) Native . loadLibrary ( "kernel32" , Kernel32 . class ); lib . Beep ( 698 , 500 ); lib . Sleep ( 500 ); lib . Beep ( 698 , 500 ); } }

انظر أيضاً

مراجع

  1. "الإصدار 5.17.0" . جيت هاب . 2025-03-16.
  2. "تعيينات الأنواع الافتراضية" . jna.dev.java.net . تم الاسترجاع في 2011-08-02 .