jnative 1.3.2版本发布了,可以完美支持C回调函数。不过令我很恼火的是还不支持activex dll的调用,问了jnative的作者,他说会在jnative 后继版本支持,大家期待吧!不然要用jacob,在一个项目里面用两种技术,我想任何人都不愿意这样做。
首先定义一个回调类模板:
然后子类继承:
最后测试:
首先定义一个回调类模板:
package com.syct.jnative.wrapper;
import java.util.ArrayList;
import java.util.List;
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.util.Callback;
public abstract class DataPackageCallback implements Callback {
private final List<Long> dataPackage;
public DataPackageCallback() {
dataPackage = new ArrayList<Long>();
}
public List getCallbackDataPackage() {
ProcessCallbackDataPackage(dataPackage);
return dataPackage;
}
public int callback(long[] values) {
// TODO Auto-generated method stub
if (values == null) {
return 3;
}
if (values.length == 2) {
try {
if (values[0] > 0) {
dataPackage.add(values[0]);
System.out.println(values[1]);
}
} catch (Exception e) {
e.printStackTrace();
}
return 1;
} else {
return 2;
}
}
//分配内存
public int getCallbackAddress() throws NativeException {
// TODO Auto-generated method stub
return JNative.createCallback(2, this);
}
//这个方法在子类实现
protected abstract void ProcessCallbackDataPackage(List<Long> dataPackage);
}
然后子类继承:
package test;
import java.util.List;
import org.xvolks.jnative.misc.basicStructures.HWND;
import org.xvolks.jnative.util.User32;
import com.syct.jnative.wrapper.DataPackageCallback;
public class MyEnumCallback extends DataPackageCallback{
StringBuffer sb=new StringBuffer();
public String getWindowEnumList(){
return sb.toString();
}
/**
* MyEnumCallback要继承DataPackageCallback
* 这个方法得到回调参数的值
*/
@Override
protected void ProcessCallbackDataPackage(List<Long> dataPackage) {
// TODO Auto-generated method stub
for (Long key : dataPackage) {
try {
//System.err.println("Handle : " + key);
String name = User32.GetWindowText(new HWND(key.intValue()));
// System.err.println("Name : " + name);
if (name == null || name.length() == 0) {
// System.err.println("Skipping handle " + key);
} else {
sb.append(name).append("\n");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
最后测试:
package test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.swing.JOptionPane;
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;
import org.xvolks.jnative.util.Callback;
import org.xvolks.jnative.util.User32;
import com.syct.jnative.wrapper.JNA_TRANS;
import com.syct.jnative.wrapper.JnaWrapper;
import com.syct.jnative.wrapper.JnaWrapperHandler;
import com.syct.jnative.wrapper.JnativeBase;
public class JnativeWrapperTest extends JnativeBase {
static String DLL_NAME = "Reader_dll";
JnaWrapper n = null;
/**
* @JNA_TRANS表明这个方法在JnativeWrapper容器中 由JnativeWrapper自动关闭jnative连接
* @return int
*/
@JNA_TRANS
public int readerInit() {
int rev = -1;
try {
n = super.initJna(DLL_NAME, "ReaderInit");
n.setRetVal(Type.INT); // 指定返回参数的类型
int i = 0;
n.setParameterInt(i++, 0);
// 指定串口
n.setParameterString(i++, "com1");
// 波特率
n.setParameterInt(i++, 9600);
// 指定usb口
n.setParameterString(i++, "usb1"); // 指定位置上的参数类型和值
// 调用方法
// 0 成功 -1 失败
rev = Integer.parseInt(n.getRetVal());
if (rev == 0) {
System.out.println("==============初始化识读头的串口成功==============");
} else if (rev == -1) {
System.out.println("==============初始化识读头的串口失败==============");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rev;
}
/**
* @JNA_TRANS表明这个方法在JnativeWrapper容器中 由JnativeWrapper自动关闭jnative连接
* @return boolean
*/
@JNA_TRANS
public boolean EnumWindows(Callback lpEnumFunc, int lParam)
throws NativeException, IllegalAccessException {
n = super.initJna("User32.dll", "EnumWindows");
n.setRetVal(Type.INT);
n.setParameterCallback(0, lpEnumFunc.getCallbackAddress());
n.setParameterInt(1, lParam);
;
return !"0".equals(n.getRetVal());
}
public void testCallback() {
try {
User32.MessageBox(0, "Callback Demo", "JNative", 0);
} catch (NativeException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalAccessException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
MyEnumCallback c = new MyEnumCallback();
try {
MemoryBlockFactory.createMemoryBlock(1).dispose();
if (EnumWindows(c, 0)) {
System.err.println("EnumWindows suceeded");
} else {
System.err.println("EnumWindows failed");
}
System.err.println("getAvailableCallbacks "
+ JNative.getAvailableCallbacks());
JNative.releaseCallback(c);
System.err.println(c.getCallbackDataPackage());
User32.MessageBox(0, c.getWindowEnumList(), "窗体枚举(EnumWindows)", 0);
JOptionPane.showMessageDialog(null, c.getWindowEnumList(),
"窗体枚举(EnumWindows)", JOptionPane.OK_OPTION);
} catch (NativeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private interface MyFactory {
public Object newInstance(int a, char[] b, String d);
}
public static void main(String[] args) {
/**
* JnativeWrapperTest 要继承JnativeBase 通过JnaWrapperProxy返回一个代理实例
*/
JnativeWrapperTest
test=(JnativeWrapperTest)JnaWrapperHandler.getJnaWrapperProxy(JnativeWrapperTest.class);
// test.readerInit();
test.testCallback();
}
}