一、下载jna.jar
https://github.com/java-native-access/jna
二 、jna使用的官方文档如下
http://java-native-access.github.io/jna/4.2.1/
三、编写so代码如下
1 /* 2 * ===================================================================================== 3 * 4 * Filename: TestDll1.cpp 5 * 6 * Description: 7 * 8 * Version: 1.0 9 * Created: 2015年12月24日 22时50分22秒 10 * Revision: none 11 * Compiler: gcc 12 * 13 * Author: yifan (), zhangzhy@suninfo.com 14 * Organization: 15 * 16 * ===================================================================================== 17 */ 18 #include <string.h> 19 #include <wchar.h> 20 21 #define MYLIBAPI extern "C" 22 23 MYLIBAPI void say(wchar_t *pValue); 24 25 struct UserStruct{ 26 long id; 27 wchar_t *name; 28 int age; 29 }; 30 31 MYLIBAPI void sayUser(UserStruct *pUserStruct); 32 33 struct CompanyStruct{ 34 long id; 35 wchar_t *name; 36 UserStruct users[100]; 37 int count; 38 }; 39 40 struct CompanyStruct2{ 41 long id; 42 wchar_t *name; 43 UserStruct *users[100]; 44 int count; 45 }; 46 #pragma pack(1) 47 struct NestedStruct{ 48 char pwd[16]; 49 char key[16]; 50 char padding[113]; 51 }; 52 53 struct SimpleStruct{ 54 NestedStruct nested; 55 int a; 56 unsigned char b; 57 int c; 58 int d; 59 char name[100]; 60 }; 61 #pragma pack() 62 MYLIBAPI void sayCompany(CompanyStruct* pCompanyStruct); 63 MYLIBAPI void sayCompany2(CompanyStruct2 *pCompanyStruct); 64 MYLIBAPI void getCompany(CompanyStruct *pCompanyStruct); 65 MYLIBAPI void getSimpleStruct(SimpleStruct *simp); 66 MYLIBAPI void saySimpleStruct(SimpleStruct *simp); 67 68 #include <iostream> 69 70 void say(wchar_t *pValue){ 71 std::wcout<<L"上帝说: "<<pValue<<std::endl; 72 } 73 74 void sayUser(UserStruct *pUserStruct){ 75 76 std::wcout<<L"ID: "<<pUserStruct->id<<std::endl; 77 std::wcout<<L"姓名: "<<pUserStruct->name<<std::endl; 78 std::wcout<<L"年龄: "<<pUserStruct->age<<std::endl; 79 } 80 81 void sayCompany(CompanyStruct *pCompanyStruct){ 82 83 std::wcout<<L"ID: "<<pCompanyStruct->id<<std::endl; 84 std::wcout<<L"公司名称: "<<pCompanyStruct->name<<std::endl; 85 std::wcout<<L"员工总数: "<<pCompanyStruct->count<<std::endl; 86 87 for (int i = 0; i < pCompanyStruct->count; i++){ 88 sayUser(&pCompanyStruct->users[i]); 89 } 90 91 } 92 93 void sayCompany2(CompanyStruct2 *pCompanyStruct){ 94 95 96 std::wcout<<L"ID: "<<pCompanyStruct->id<<std::endl; 97 std::wcout<<L"公司名称: "<<pCompanyStruct->name<<std::endl; 98 std::wcout<<L"员工总数: "<<pCompanyStruct->count<<std::endl; 99 100 for (int i = 0; i < pCompanyStruct->count; i++){ 101 sayUser(pCompanyStruct->users[i]); 102 } 103 } 104 105 void getCompany(CompanyStruct *pCompanyStruct){ 106 pCompanyStruct->count = 1; 107 wcscpy(pCompanyStruct->name, L"Out Name"); 108 pCompanyStruct->id = 13; 109 } 110 111 void getSimpleStruct(SimpleStruct *simp){ 112 simp->a = 1; 113 simp->b = 2; 114 simp->c = 3; 115 simp->d = 4; 116 memset(simp->name, 0, sizeof(simp->name)); 117 strcpy(simp->name, "test"); 118 memset(&simp->nested, 0, sizeof(NestedStruct)); 119 strcpy(simp->nested.pwd, "pwd"); 120 strcpy(simp->nested.key, "key"); 121 } 122 123 void saySimpleStruct(SimpleStruct *simp){ 124 std::wcout<<L"simp->a = "<<simp->a<<std::endl; 125 std::wcout<<L"simp->b = "<<simp->b<<std::endl; 126 std::wcout<<L"simp->c = "<<simp->c<<std::endl; 127 std::wcout<<L"simp->d = "<<simp->d<<std::endl; 128 std::wcout<<L"simp->name = "<<simp->name<<std::endl; 129 std::wcout<<L"simp->nested.pwd ="<<simp->nested.pwd<<std::endl; 130 std::wcout<<L"simp->nested.key ="<<simp->nested.key<<std::endl; 131 }
四、编写java测试代码如下:
1 //package com.sun.jna; 2 3 4 import java.util.ArrayList; 5 import java.util.Arrays; 6 import java.util.List; 7 import java.util.Map; 8 9 10 import com.sun.jna.Library; 11 import com.sun.jna.Native; 12 import com.sun.jna.NativeLong; 13 import com.sun.jna.Structure; 14 import com.sun.jna.WString; 15 16 17 public class TestDll1Service { 18 19 /* 20 * 定义一个类,模拟C语言的结构 21 * 22 */ 23 24 public static class UserStruct extends Structure{ 25 26 public static class ByReference extends UserStruct implements Structure.ByReference { 27 public ByReference() {} 28 //public ByReference(Pointer p){ super(p);} 29 } 30 public static class ByValue extends UserStruct implements Structure.ByValue { 31 public ByValue() {} 32 //public ByValue(Pointer p) { super(p);} 33 } 34 35 public NativeLong id; 36 public WString name; 37 public int age; 38 39 // 字段顺序与SO中结构体声明一致 40 protected List getFieldOrder() { 41 return Arrays.asList(new String[] { 42 "id", "name", "age" 43 }); 44 } 45 } 46 47 public static class CompanyStruct extends Structure{ 48 public static class ByReference extends CompanyStruct implements Structure.ByReference { 49 public ByReference() {} 50 //public ByReference(Pointer p){ super(p);} 51 } 52 53 public static class ByValue extends CompanyStruct implements Structure.ByValue { 54 public ByValue() {} 55 //public ByValue(Pointer p) { super(p);} 56 } 57 58 public NativeLong id; 59 public WString name; 60 // 嵌套的结构体数组,下面三种声明都可以,注意每种声明的赋值方式 61 // Declare 1 62 // public UserStruct[] users = (UserStruct[])new UserStruct().toArray(100); 63 // Declare 2 64 // public UserStruct.ByValue[] users = new UserStruct.ByValue[100]; 65 // Declare 3 66 public UserStruct[] users = new UserStruct[100]; 67 public int count; 68 69 protected List getFieldOrder() { 70 return Arrays.asList(new String[] { 71 "id", "name", "users", "count" 72 }); 73 } 74 75 76 } 77 78 public static class CompanyStruct2 extends Structure{ 79 public static class ByReference extends CompanyStruct2 implements Structure.ByReference { 80 public ByReference() {} 81 //public ByReference(Pointer p){ super(p);} 82 } 83 84 public static class ByValue extends CompanyStruct2 implements Structure.ByValue { 85 public ByValue() {} 86 //public ByReference(Pointer p){ super(p);} 87 } 88 89 public NativeLong id; 90 public WString name; 91 // 嵌套的结构体指针数组 92 public UserStruct.ByReference[] users=new UserStruct.ByReference[100]; 93 public int count; 94 95 protected List getFieldOrder() { 96 return Arrays.asList(new String[] { 97 "id", "name", "users", "count" 98 }); 99 } 100 101 102 } 103 104 public static class NestedStruct extends Structure{ 105 public static class ByValue extends NestedStruct implements Structure.ByValue{} 106 // 声明内存对齐方式,与SO中声明的结构体对齐保持一致 107 public NestedStruct() {super(ALIGN_NONE);} 108 109 // 注意C/C++中的char 对应java中的byte,其它类型之间的映射请参考官方文档 110 public byte pwd[] = new byte[16]; 111 public byte key[] = new byte[16]; 112 public byte padding[] = new byte[113]; 113 114 protected List getFieldOrder(){ 115 return Arrays.asList(new String[]{ 116 "pwd", "key", "padding"}); 117 } 118 } 119 120 public static class SimpleStruct extends Structure{ 121 public static class ByReference extends SimpleStruct implements Structure.ByReference{} 122 public NestedStruct.ByValue nested = new NestedStruct.ByValue(); 123 public int a; 124 public byte b; 125 public int c; 126 public int d; 127 public byte name[] = new byte[100]; 128 129 public SimpleStruct(){super(ALIGN_NONE);}; 130 protected List getFieldOrder(){ 131 return Arrays.asList(new String[]{ 132 "nested", "a", "b", "c", "d", "name" 133 }); 134 } 135 } 136 137 138 public interface TestDll1 extends Library { 139 /** 140 * 当前路径是在项目下,而不是bin输出目录下。 141 */ 142 TestDll1 INSTANCE = (TestDll1)Native.loadLibrary("TestDll1", TestDll1.class); 143 144 145 public void say(WString value); 146 147 148 149 public void sayUser(UserStruct.ByReference struct); 150 151 152 153 public void sayCompany(CompanyStruct.ByReference pCompanyStruct); 154 155 public void sayCompany2(CompanyStruct2.ByReference pCompanyStruct); 156 157 //public void getCompany(CompanyStruct.ByReference pCompanyStruct); 158 public void getSimpleStruct(SimpleStruct simp); 159 public void getSimpleStruct(SimpleStruct.ByReference simp); 160 public void saySimpleStruct(SimpleStruct simp); 161 162 } 163 public class TestClass{ 164 int a; 165 int b; 166 } 167 168 169 /** 170 * @param args 171 */ 172 public static void main(String[] args) { 173 // TODO Auto-generated method stub 174 175 TestDll1.INSTANCE.say(new WString("Hello World!")); 176 System.out.println("HHEEH中文"); 177 178 179 UserStruct.ByReference userStruct = new UserStruct.ByReference(); 180 userStruct.id = new NativeLong(100); 181 userStruct.age = 30; 182 userStruct.name = new WString("yifan"); 183 TestDll1.INSTANCE.sayUser(userStruct); 184 System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAA"); 185 186 CompanyStruct.ByReference companyStruct = new CompanyStruct.ByReference(); 187 companyStruct.id = new NativeLong(1); 188 companyStruct.name = new WString("Google"); 189 companyStruct.count = 9; 190 System.out.println("UserStruct size = " + userStruct.size()); 191 System.out.println("CompanyStruct size = " + companyStruct.size()); 192 for(int i = 0; i < companyStruct.count; i++){ 193 /* 194 * Declare 1 195 companyStruct.users[i].id = new NativeLong(i); 196 companyStruct.users[i].name = new WString("yifan" + i); 197 companyStruct.users[i].age = 20 + i; 198 */ 199 /* 200 * Declare 2 201 UserStruct.ByValue user = new UserStruct.ByValue(); 202 user.id = new NativeLong(i + 1); 203 user.name = new WString("yifan" + i); 204 user.age = 20 + i; 205 companyStruct.users[i] = user; 206 */ 207 /* 208 * Declare 3 209 */ 210 UserStruct user2 = new UserStruct(); 211 user2.id = new NativeLong(i); 212 user2.name = new WString("yifan " + i); 213 user2.age = 20 + i; 214 companyStruct.users[i] = user2; 215 } 216 TestDll1.INSTANCE.sayCompany(companyStruct); 217 218 System.out.println("++++++++++++++"); 219 220 CompanyStruct2.ByReference companyStruct2 = new CompanyStruct2.ByReference(); 221 companyStruct2.id = new NativeLong(2); 222 companyStruct2.name = new WString("Yahoo"); 223 companyStruct2.count = 10; 224 System.out.println("CompanyStruct2 size = " + companyStruct2.size()); 225 for(int i = 0;i < companyStruct2.count; i++){ 226 companyStruct2.users[i] = new UserStruct.ByReference(); 227 companyStruct2.users[i].id = new NativeLong(i); 228 companyStruct2.users[i].name = new WString("Yahoo user" + i); 229 companyStruct2.users[i].age = 20 + i; 230 } 231 //companyStruct.write(); 232 TestDll1.INSTANCE.sayCompany2(companyStruct2); 233 234 System.out.println("CCCCCCCCCCCCCCCCCCCCCCCCCCCC"); 235 SimpleStruct.ByReference simple = new SimpleStruct.ByReference(); 236 TestDll1.INSTANCE.getSimpleStruct(simple); 237 System.out.println("simple: size = " + simple.size()); 238 System.out.println("simple: a = " + simple.a); 239 System.out.println("simple: b = " + simple.b); 240 System.out.println("simple: c = " + simple.c); 241 System.out.println("simple: d = " + simple.d); 242 System.out.println("simple: name = " + new String(simple.name)); 243 System.out.println("simple: nested: pwd = " + new String(simple.nested.pwd)); 244 System.out.println("simple: nested: key = " + new String(simple.nested.key)); 245 System.out.println("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"); 246 247 SimpleStruct simp2 = new SimpleStruct(); 248 byte[] pwd = "simp2_pwd".getBytes(); 249 byte[] key = "simp2_key".getBytes(); 250 byte[] name = "simp2".getBytes(); 251 simp2.a = 5; 252 simp2.b = 6; 253 simp2.c = 7; 254 simp2.d = 8; 255 // 256 // 对于已经声明大小的数组,使用下面数组赋值方式, 257 // 不要使用simp2.nested.pwd = "11".getBytes() 这种赋值方式 258 // 259 260 System.arraycopy(name, 0, simp2.name, 0, name.length); 261 System.arraycopy(pwd, 0, simp2.nested.pwd, 0, pwd.length); 262 System.arraycopy(key, 0, simp2.nested.key, 0, key.length); 263 TestDll1.INSTANCE.saySimpleStruct(simp2); 264 System.out.println("EEEEEEEEEEEEEEEEEEEEEEEEEEEEE"); 265 266 267 } 268 269 }
五、编译代码
由于本人没有安装Java相关IDE,使用命令行进行编译运行。
1、编译so库
g++ -fPIC -shared -o libTestDll1.so TestDll1.cpp
2、编译java,将下载的jna放到测试的代码目录
javac -classpath jna-4.2.1.jar TestDll1Service.java
3、运行class 文件
java -classpath .:jna-4.2.1.jar TestDll1Service
4、运行结果如下
上帝说: Hello World! HHEEH中文 ID: 100 姓名: yifan 年龄: 30 AAAAAAAAAAAAAAAAAAAAAAAAAAA UserStruct size = 24 CompanyStruct size = 2424 ID: 1 公司名称: Google 员工总数: 9 ID: 0 姓名: yifan0 年龄: 20 ID: 1 姓名: yifan1 年龄: 21 ID: 2 姓名: yifan2 年龄: 22 ID: 3 姓名: yifan3 年龄: 23 ID: 4 姓名: yifan4 年龄: 24 ID: 5 姓名: yifan5 年龄: 25 ID: 6 姓名: yifan6 年龄: 26 ID: 7 姓名: yifan7 年龄: 27 ID: 8 姓名: yifan8 年龄: 28 ++++++++++++++ ID: 2 公司名称: Yahoo 员工总数: 10 ID: 0 姓名: Yahoo user0 年龄: 20 ID: 1 姓名: Yahoo user1 年龄: 21 ID: 2 姓名: Yahoo user2 年龄: 22 ID: 3 姓名: Yahoo user3 年龄: 23 ID: 4 姓名: Yahoo user4 年龄: 24 ID: 5 姓名: Yahoo user5 年龄: 25 ID: 6 姓名: Yahoo user6 年龄: 26 ID: 7 姓名: Yahoo user7 年龄: 27 ID: 8 姓名: Yahoo user8 年龄: 28 ID: 9 姓名: Yahoo user9 年龄: 29 CCCCCCCCCCCCCCCCCCCCCCCCCCCC simple: size = 258 simple: a = 1 simple: b = 2 simple: c = 3 simple: d = 4 simple: name = test simple: nested: pwd = pwd simple: nested: key = key DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD simp->a = 5 simp->b = 6 simp->c = 7 simp->d = 8 simp->name = simp2 simp->nested.pwd =simp2_pwd simp->nested.key =simp2_key