java调用C 函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java调用C 函数相关的知识,希望对你有一定的参考价值。

现在要用java调用 C 的函数完成一些功能.
使用jawin 来调用 C,

首先是C的函数说明:
cli_sys_EnumerateDeviceType(unsigned int uindex, char **sdevtype);
功能说明:枚举所有支持的设备类型
输入参数:uindex - 从0 开始递增的序号
输出参数:sdevtype - 返回的设备类型字串指针
函数返回:RET_SUCC:执行成功 / RET_FAIL:执行失败 / RET_USPT:不支持该方法

我现在要用jawin调用这个函数,然后获取所有的设备类型的字符串表示
下面是我的代码,但没有完成预期的目标,请大家帮个忙.

package com.zhihai.wangkai.monitor;

import java.io.ByteArrayInputStream;

import org.jawin.COMException;
import org.jawin.FuncPtr;
import org.jawin.ReturnFlags;
import org.jawin.io.LittleEndianInputStream;
import org.jawin.io.LittleEndianOutputStream;
import org.jawin.io.NakedByteStream;

public class CallSoftDll

public static void main(String[] args) throws Exception
FuncPtr monitorDevice = null;
try
byte[] result=null;
monitorDevice = new FuncPtr("D:\\wangkai\\monitor_sdk\\DVRClientLayer.dll", "cli_sys_EnumerateDeviceType");
NakedByteStream nbs = new NakedByteStream();
LittleEndianOutputStream leos = new LittleEndianOutputStream(nbs);
leos.writeInt(0);
result = monitorDevice.invoke("I:I:A", 4, nbs, null, ReturnFlags.CHECK_NONE);
LittleEndianInputStream leis = new LittleEndianInputStream(new ByteArrayInputStream(result));

for(int i=0;i<result.length;i++)
System.out.print(result[i]);

// System.out.println(leis.readLine());

catch (COMException e)
e.printStackTrace();
throw e;
finally
if (monitorDevice != null)
try
monitorDevice.close();
catch (COMException e)
// handle fatal exception
e.printStackTrace();
throw e;





利用java的JNI技术,具体内容贴出来太多,网上也有很多这个资料,楼主可以做个参考 参考技术A 需要jni

Java回调函数

  维基百科上的定义:在计算机程序设计中,回调函数,或简称回调,是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。

  所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调用C中的某个函数B,对于C来说,这个B便叫做回调函数。一般说来,C不会自己调用B,C提供B的目的就是让S来调用它,而且是C不得不提供。由于S并不知道C提供的B姓甚名谁,所以S会约定B的接口规范(函数原型),然后由C提前通过S的一个函数R告诉S自己将要使用B函数,这个过程称为回调函数的注册,R称为注册函数。Web Service以及Java的RMI都用到回调机制,可以访问远程服务器程序。回调更多的应用就是结合异步。

  下面举个通俗的例子:某天,我打电话向你请教问题,你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。故事到此结束。这个例子说明了“异步+回调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机能够接收到你的呼叫,这是回调函数必须符合接口规范。

  下面给出两个示例。

示例1:

 1.  首先定义一个类Caller,按照上面的定义就是程序员A写的程序a,这个类里面保存一个接口引用。

 1 public class Caller {  
 2     private MyCallInterface callInterface;  
 3       
 4     public Caller() {  
 5     }  
 6       
 7     public void setCallFunc(MyCallInterface callInterface) {  
 8         this.callInterface = callInterface;  
 9     }  
10       
11     public void call() {  
12         callInterface.printName();  
13     }  
14 }  

2.  当然需要接口的定义,为了方便程序员B根据我的定义编写程序实现接口。

1 public interface MyCallInterface {  
2     public void  printName();  
3 }  

3.  第三是定义程序员B写的程序b

1 public class Client implements MyCallInterface {  
2   
3     @Override  
4     public void printName() {  
5         System.out.println("This is the client printName method");  
6     }  
7 }  

4.  测试如下

1 public class Test {  
2     public static void main(String[] args) {  
3         Caller caller = new Caller();  
4         caller.setCallFunc(new Client());  
5         caller.call();  
6     }  
7 }  

看到这里应该明白什么是回调了,有些文章介绍的很好,但是刚开始没看明白,是因为把第3步的类省略,直接写成匿名类了。

5. 在测试方法中直接使用匿名类,省去第3步。

 1 public class Test {  
 2     public static void main(String[] args) {  
 3         Caller caller = new Caller();  
 4 //      caller.setCallFunc(new Client());  
 5         caller.setCallFunc(new MyCallInterface() {  
 6             public void printName() {  
 7                 System.out.println("This is the client printName method");  
 8             }  
 9         });  
10         caller.call();  
11     }  
12 }  

示例2:

如果我们要测试一个类的方法的执行时间,通常我们会这样做:

 1 public   class  TestObject {  
 2     /**  
 3      * 一个用来被测试的方法,进行了一个比较耗时的循环  
 4      */   
 5     public   static   void  testMethod(){  
 6         for ( int  i= 0 ; i< 100000000 ; i++){  
 7               
 8         }  
 9     }  
10     /**  
11      * 一个简单的测试方法执行时间的方法  
12      */   
13     public   void  testTime(){  
14         long  begin = System.currentTimeMillis(); //测试起始时间   
15         testMethod(); //测试方法   
16         long  end = System.currentTimeMillis(); //测试结束时间   
17         System.out.println("[use time]:"  + (end - begin)); //打印使用时间   
18     }  
19       
20     public   static   void  main(String[] args) {  
21         TestObject test=new  TestObject();  
22         test.testTime();  
23     }  
24 }  

大家看到了testTime()方法,就只有"//测试方法"是需要改变的,下面我们来做一个函数实现相同功能但更灵活:

首先定一个回调接口:

1 public   interface  CallBack {  
2     //执行回调操作的方法   
3     void  execute();  
4 }  

然后再写一个工具类:

 1 public   class  Tools {  
 2       
 3     /**  
 4      * 测试函数使用时间,通过定义CallBack接口的execute方法  
 5      * @param callBack  
 6      */   
 7     public   void  testTime(CallBack callBack) {  
 8         long  begin = System.currentTimeMillis(); //测试起始时间   
 9         callBack.execute(); ///进行回调操作   
10         long  end = System.currentTimeMillis(); //测试结束时间   
11         System.out.println("[use time]:"  + (end - begin)); //打印使用时间   
12     }  
13       
14     public   static   void  main(String[] args) {  
15         Tools tool = new  Tools();  
16         tool.testTime(new  CallBack(){  
17             //定义execute方法   
18             public   void  execute(){  
19                 //这里可以加放一个或多个要测试运行时间的方法   
20                 TestObject.testMethod();  
21             }  
22         });  
23     }  
24       
25 }  

testTime()传入定义callback接口的execute()方法就可以实现回调功能

 

参考:http://kidult.iteye.com/blog/148982

http://blog.csdn.net/allen_zhao_2012/article/details/8056665

http://blog.csdn.net/fengyifei11228/article/details/5729445

以上是关于java调用C 函数的主要内容,如果未能解决你的问题,请参考以下文章

使用 Eclipse 从 Android 中的 C 代码调用 Java 函数而不调用 Java

从 Java 调用 c 函数

java 调用C写的DLL

JAVA中如何调用API函数?

java里面,c里面都有回调函数,回调函数都是啥东西啊???

Android使用JNI,C++调用JAVA代码,能找到JAVA的函数无法调用?