Java on Linux uses JNA to call C/C++ functions to pass parameters (arrays, two-dimensional arrays)

Steps to call C/C++ functions using JNA:

1. Define the JNA interface API (C/C++).h file
2. Implement the functions defined in the .h file (.c) file
3. Compile the .c file to generate a dynamic library file (.so)
4. Apply the JNA package jna-*.jar, I use jna-5.6.0.jar here
5. Define the java interface, load the dynamic library, and define the corresponding API method
6. Call the corresponding method through the java interface

Tested today, one-dimensional array and two-dimensional array parameter passing between java and C/C++ functions.

one-dimensional array

The one-dimensional array is relatively simple, directly upload the code:
1. testJNA.h

#include <stdio.h>
void printfArray(int arr[]);

2、testJNA.c

#include "testJNA.h"
void printfArray(int arr[]) {
    
    
    printf("input【%d】",arr[0]);
}

3、Clibrary.java

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

public interface Clibrary extends Library {
    
    
    Clibrary INSTANCE = (Clibrary) Native.load("testJNA", Clibrary.class);
    void printfArray(int[] arr);
}

4. Call

    public static void main(String[] args) {
    
    
        int[] a = new int[]{
    
    1,2};
        Clibrary.INSTANCE.printfArray(a);
    }

Two-dimensional array

Two-dimensional arrays are more troublesome, because JNA cannot automatically convert java two-dimensional arrays into C two-dimensional arrays (maybe it is supported, I am not familiar with it and have not found a corresponding method, if there is a better method, please leave a message for advice), I am here Customized an object
1, testJNA.h

#include <stdio.h>

typedef struct
{
    
    
    int a[2];
}Ershuzu;

void printfERArray(Ershuzu arr[],int size);

2、testJNA.c

#include "testJNA.h"

void printfERArray(Ershuzu arr[],int size) {
    
    
    for(int i = 0;i < size; i++) {
    
    
        for(int j = 0;j < 2;j++)
        printf("arr[%d][%d]input【%d】",i,j,arr[i].a[j]);
    }
}

3. Ershuzu.java

import com.sun.jna.Structure;

import java.util.Arrays;
import java.util.List;

public class Ershuzu extends Structure {
    
    
    public int[] a = new int[2];
    public static class ByReference extends Ershuzu implements Structure.ByReference {
    
    }
    public static class ByValue extends Ershuzu implements Structure.ByValue {
    
    }

    @Override
    protected List<String> getFieldOrder() {
    
    
        return Arrays.asList(new String[]{
    
    "a"});
    }
}

4、Clibrary.java

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

public interface Clibrary extends Library {
    
    
    Clibrary INSTANCE = (Clibrary) Native.load("testJNA", Clibrary.class);

   void printfERArray(Ershuzu[] er,int size);
}

5. Call

   public static void main(String[] args) {
    
    
        Ershuzu[] ershuzus = (Ershuzu[]) new Ershuzu().toArray(2);
        ershuzus[0].a = new int[]{
    
    1,2};
        ershuzus[1].a = new int[]{
    
    3,4};
        Clibrary.INSTANCE.printfERArray(ershuzus,ershuzus.length);
   }

compile test

Put the .h and .c files in the same directory for compilation

gcc -m64 -fPIC -c ./*.c -I./ -std=c99
gcc -m64 -shared -o libtestJNA.so *.o
rm -f *.o
javac -cp :./jna-5.6.0.jar TestJNA.java
java -cp :./jna-5.6.0.jar TestJNA

Guess you like

Origin blog.csdn.net/wzl19870309/article/details/110771531