linux 环境下java 使用jna调用so库方法


一、下载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

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM