2014-01-20 227 views
2

我正在製作一個項目,其中涉及使用JNA將二維數組從Java傳遞到C++。但我在傳遞二維數組時遇到問題。我能夠毫無問題地傳遞一維數組。如何使用JNA將二維數組從Java傳遞到C

Java代碼 -

import com.sun.jna.Library; 
import com.sun.jna.Native; 

public class HelloWorld { 
    public static void main(String argv[]) { 
     CTest lib = CTest.ctest; 
     int a[][] = {{2, 3}, {2, 4}}; 
     System.out.println(lib.helloFromC(a)); 
    } 
    public interface CTest extends Library { 
     CTest ctest = (CTest) Native.loadLibrary("cpptest", CTest.class); 
     public int helloFromC(int x[][]); 
    } 

} 

C++代碼

#include <stdio.h> 
extern "C" __declspec(dllexport) 
int helloFromC(int a[][2]) { 

    int i, sum = 0, j; 
    for(i=0;i<2;i++) { 
    for(j=0;j<2;j++) { 
    printf("%d\n",a[i][j]); 
     sum += a[i][j];} 
    } 
    printf("%d\n",sum); 
    return sum; 
} 

當我編譯這兩個文件,我沒有錯誤,但是當我運行java文件,我得到,

Exception in thread "main" java.lang.IllegalArgumentException: Unsupported array 
argument type: class [I 
     at com.sun.jna.Function.convertArgument(Function.java:609) 
     at com.sun.jna.Function.invoke(Function.java:297) 
     at com.sun.jna.Library$Handler.invoke(Library.java:212) 
     at $Proxy0.helloFromC(Unknown Source) 
     at HelloWorld.main(HelloWorld.java:8) 
+0

許多元素你確定'int a [] [2]'是一個有效的參數嗎? –

+0

@SotiriosDelimanolis:不,我不確定..我第一次使用JNA – user3215014

回答

2

在JNA中,當您在Java和C/C++代碼中都有原始多維數組時,您需要使用Java中的一維數組映射到ND數組以本機代碼。這是因爲Java多維數組與本地C/C++ N-D數組不同,因爲每行的Java N-D數組的內存分配是連續的不是。所以,當你使用這個在Java中

int a[][] = {{2, 3}, {2, 4}}; 

你等價使用兩個new創建一個2-d數組:所以爲了解決Java和本地代碼的問題之間的這種不匹配

int[] a = new int[2]; 
for(int i=0; i<2; i++) { 
    a[i] = new int[2]; 
} 

,你必須在Java中使用1-d陣列來模擬2-d陣列,諸如:

public static final int NUM_ROW = 2; 
public static final int NUM_COL = 2; 
int[] a = new int[NUM_ROW*NUM_COL]; 

對於1-d陣列a(i,j)th元件,使用

a[i*NUM_COL+j] 

要訪問它。你可以通過這個1-d陣列您JNA代碼

System.out.println(lib.helloFromC(a)); 

在陣列如何多維工程JNA代碼JNA API overview給出了詳細解釋。它指出的映射機制JNA是如何工作的:

要映射本地多維數組,可以使用一維的Java 陣列等同於全面的本地陣列