1.构建项目
准备最简单的maven项目,结构如下:
引入依赖:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.3.1</version>
</dependency>
2.构建c文件和so文件
在resource目录下构建:
#include <stdio.h>
test() {
printf("hello world\n");
}
编译生成so:
gcc test.c -fPIC -shared -o test.so
3.编写解析类和测试类
package org.linx;
import com.sun.jna.Library;
import com.sun.jna.Native;
public interface CLibrary extends Library {
CLibrary INSTANCE = Native.loadLibrary("test.so", CLibrary.class);
/**
* 初始化SDK 注意:调用SDK其他接口前必须先调用此接口!
*/
void test();
}
package org.linx;
import junit.framework.TestCase;
import org.junit.Test;
public class CLibraryTest extends TestCase {
@Test
public void testTest() {
CLibrary.INSTANCE.test();
}
}
tips:如果要把该项目打包为jar供其他项目使用,需要将so文件放置在特定目录下
访问不了的时候可以放在/usr/lib然后使用绝对路径
4.C与Java类型对应
C Type | Java Type |
---|---|
char | byte |
wchar_t | char |
short | short |
int 32-bit整型 | int |
int boolean flag | boolean |
enum | int (usually) |
long long | long |
float | float |
double | double |
void* | Pointer |
void** | Pointer[] |
char** 字符串数组 | String[] |
wchar_t** 字符串数组(unicode) | WString[] |
struct* struct 结构体指针和结构体 | Structure |
union 结构体 | Union |
struct[] 结构体数组 | Structure[] |
char* | ByteByReference/Pointer |
int* | IntByReference |
float* | FloatByReference |
double* | DoubleByReference |
结构体struct的写法:
@FieldOrder(value = {"x","y"})
public class Sm2PublicT extends Structure {
public byte[] x;
public byte[] y;
Sm2PublicT(){
x = new byte[64];
y = new byte[64];
}
Sm2PublicT(byte[] x, byte[] y){
this.x = x;
this.y = y;
}
// 定义值传递和指针传递类
public static class ByReference extends Sm2PublicT implements Structure.ByReference {
//指针和引用的传递使用ByReference
}
public static class ByValue extends Sm2PublicT implements Structure.ByValue {
//拷贝参数传递使用ByValue
}
}
在返回值为结构体的时候,有时返回类型不能写Sm2PublicT而应该写Sm2PublicT.ByValue
关于ByReference和ByValue
- 只要涉及到结构体的传递,必须使用ByReference或者ByValue中的一种
- 指针和引用的传递使用ByReference
- 拷贝参数传递使用ByValue
复杂的结构体传递可以参考:网址
本人实验char*可以使用Pointer:
Pointer id = new Memory(8);
id.setString(0, "myapp");
Pointer plain = new Memory(1024);
使用int*的时候:
IntByReference clen = new IntByReference(2048);