عودة C مجموعة لجافا باستخدام JNA
سؤال
وأنا لست على دراية جدا مع C، ولكن أنا بحاجة إلى استخدام مكتبة C في التعليمات البرمجية جافا بلدي. لقد خلق DLL، وأنا قادرة على الوصول إليه على ما يرام، ولكن أنا محاولة للعودة مجموعة من [إينتس] من التعليمات البرمجية C إلى رمز جافا.
في C أظن أنك يمكن أن يعود ببساطة مؤشر إلى مجموعة، ولكنه لا يعمل مثل أتوقع في جافا البرمجية بلدي. هنا هو رمز C:
int * getConusXY(double latitude, double longitude) {
maparam stcprm;
double reflat = 25, reflon = -95,
lat1 = 20.191999, lon1 = -121.54001,
x1 = 0, y1 = 0, x2 = 1073, y2 = 689,
gsize = 5.079, scaLat = 25, scaLon = -95, orient = 0;
double x, y;
int* xy;
xy = malloc(2 * sizeof *xy);
stlmbr(&stcprm, reflat, reflon);
stcm1p(&stcprm, x1, y1, lat1, lon1, scaLat, scaLon, gsize, orient);
cll2xy(&stcprm, latitude, longitude, &x, &y);
xy[0] = (int) x;
xy[1] = (int) y;
return xy;
}
إذا كنت اختبار هذا في C ++ عن طريق القيام
int* xy = getConusXY(33.92, -84.33);
cout << xy[0] << " " << xy[1] << endl;
وبعد ذلك يعمل بشكل جيد وأحصل على القيم 739، 255 كما كان متوقعا.
وأنا أحاول استخدامه في جاوة مع حزمة JNA مثل ذلك (ولكن هذا يعطيني 739، -16777214):
public class DmapFDllLibrary {
interface DmapFLibrary extends Library {
DmapFLibrary INSTANCE = (DmapFLibrary) Native.loadLibrary("DmapFDll",
DmapFLibrary.class);
IntByReference getConusXY(double latitude, double longitude);
}
public static void main(String... strings) {
IntByReference xy_ref = DmapFLibrary.INSTANCE.getConusXY(33.92, -84.33);
Pointer p = xy_ref.getPointer();
System.out.println(p.getInt(0) + " " + p.getInt(1));
}
}
في وثائق JNA تقول انها صفائف البدائية مثل int *buf
يتم تعيينها إلى int[] buf
في جاوة، ولكن عندما أحاول تغيير نوع الإرجاع من IntByReference
إلى int[]
ثم أحصل على illegalArgumentException.
وأنا لا أعرف ما إذا كنت أعود للمجموعة بشكل صحيح من C أو إذا أنا فقط لا الوصول إليه بشكل صحيح في جاوة. أي مساعدة سيكون موضع تقدير.
المحلول
وأنا لن تستخدم مثل هذه الوظيفة، لأنه لن تكون أبدا سراح مجموعة عاد / حذف. ولكنني تغيير وظيفة C إذا ما بوسعي ل:
<اقتباس فقرة> وvoid myFunc(Pointer resuls, int numBytes, byte const * returnArray)
نصائح أخرى
والرمز C <الصورة> على ما يرام ث> يجب أن يكون أفضل (انظر تعليقات أخرى)، ومع ذلك، فإن القضية الرئيسية هي أن كنت إساءة استخدام طريقة getInt()
جافا للمؤشر. ويبدو لي أن أستعمل getIntArray()
.
والتفسير لفترة أطول وربما أكثر وضوحا هو أنك النموذج الأولي وظيفة جافا لتلقي مؤشر (أو خليفة المؤشر) -
byte[] myFunc(Pointer result, int numBytes);
وعند إنشاء الاستدعاء نفسها، يمكنك استخدام getByteArray (الباحث)، أو واحد من getArrays البعض.
byte[] myFunc(Pointer resuls, int numBytes)
{
return Pointer.getByteArray(numBytes);
}