其实本来就是闲的蛋疼,有个开发板,以前用VC,VB些过测试程序,,一时心血来潮,想弄个JAVA来控制下开发板玩玩
没想到遇到了个问题卡壳了,,, 做过技术的人应该都能理解我的心情吧 呵呵前前后后,已经送了1000分了对于这个问题, 但是还是没有解决掉,,前面的帖子都结了也这次送1000分,问题解决后,另开贴9个帖子送分。
外加3合1的ARM开发板一块,配件齐全,但邮费需要自付。我的问题如下,先列下我参考的代码,如下:假设我们现在有这样一个C语言结构体
struct UserStruct{
long id;
wchar_t* name;
int age;
};使用上述结构体的函数
#define MYLIBAPI extern "C" __declspec( dllexport )
MYLIBAPI void sayUser(UserStruct* pUserStruct);
对应的Java程序中,在例1的 接口中添加下列代码:
public static class UserStruct extends Structure{
public NativeLong id;
public WString name;
public int age;
public static class ByReference extends UserStruct implements Structure.ByReference { }
public static class ByValue extends UserStruct implements Structure.ByValue
{ }
}
public void sayUser(UserStruct.ByReference struct);Java中的调用代码:
UserStruct userStruct=new UserStruct ();
userStruct.id=new NativeLong(100);
userStruct.age=30;
userStruct.name=new WString("奥巴马"); TestDll1.INSTANCE.sayUser(userStruct); 我觉得这段代码和我的应该比较类似的, 我做了如下的声明,请高手帮看看哪里有问题谢谢
首先模仿结构的声明:
public static class UserStruct extends Structure{
public static class ByReference extends UserStruct implements Structure.ByReference { }
public static class ByValue extends UserStruct implements Structure.ByValue { }
public int Address;
public int Length;
public byte num[][]=new byte[8][30];
}
接口函数里做如下模仿
public static interface RFSAPIV2 extends Library {
RFSAPIV2 INSTANCE = (RFSAPIV2)
Native.loadLibrary("RFSAPIV2",
RFSAPIV2.class);
int ReadLabelID(long hh,int nMax, UserStruct.ByReference idBuffer,int[] nCounter);
} 在按钮过程中做如下
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
UserStruct idBuffer = new UserStruct();
idBuffer.Address=0;
idBuffer.Length=0;
idBuffer.num[0][0]=(byte)0x00; // 这地方没有把数组全面初始化不知道影响否??? int nCounter[]={0};
int nMax=10; apiReturn=RFSAPIV2.INSTANCE.ReadID(hScanner[0], nMax, idBuffer, nCounter);
} 做语法检查时,,提示上面的函数调用部分的红色字体,即第三个参数 错误。
“
无法将 接口 desktopapplication2.DesktopApplication2View.RFSAPIV2 中的 方法 ReadID 应用于 long,int,desktopapplication2.DesktopApplication2View.UserStruct.ByReference,int[](long,int,desktopapplication2.DesktopApplication2View.UserStruct,int[])
--
(按 Alt-Enter 组合键可显示提示)
”
请指导一下 ,谢谢。
指导解决问题后,送1000分,外加3合1 ARM开发板一块(邮资自付)
本人结贴即使,可参加近几天的结贴情况,已经前后送出了1000分了,就这个问题
没想到遇到了个问题卡壳了,,, 做过技术的人应该都能理解我的心情吧 呵呵前前后后,已经送了1000分了对于这个问题, 但是还是没有解决掉,,前面的帖子都结了也这次送1000分,问题解决后,另开贴9个帖子送分。
外加3合1的ARM开发板一块,配件齐全,但邮费需要自付。我的问题如下,先列下我参考的代码,如下:假设我们现在有这样一个C语言结构体
struct UserStruct{
long id;
wchar_t* name;
int age;
};使用上述结构体的函数
#define MYLIBAPI extern "C" __declspec( dllexport )
MYLIBAPI void sayUser(UserStruct* pUserStruct);
对应的Java程序中,在例1的 接口中添加下列代码:
public static class UserStruct extends Structure{
public NativeLong id;
public WString name;
public int age;
public static class ByReference extends UserStruct implements Structure.ByReference { }
public static class ByValue extends UserStruct implements Structure.ByValue
{ }
}
public void sayUser(UserStruct.ByReference struct);Java中的调用代码:
UserStruct userStruct=new UserStruct ();
userStruct.id=new NativeLong(100);
userStruct.age=30;
userStruct.name=new WString("奥巴马"); TestDll1.INSTANCE.sayUser(userStruct); 我觉得这段代码和我的应该比较类似的, 我做了如下的声明,请高手帮看看哪里有问题谢谢
首先模仿结构的声明:
public static class UserStruct extends Structure{
public static class ByReference extends UserStruct implements Structure.ByReference { }
public static class ByValue extends UserStruct implements Structure.ByValue { }
public int Address;
public int Length;
public byte num[][]=new byte[8][30];
}
接口函数里做如下模仿
public static interface RFSAPIV2 extends Library {
RFSAPIV2 INSTANCE = (RFSAPIV2)
Native.loadLibrary("RFSAPIV2",
RFSAPIV2.class);
int ReadLabelID(long hh,int nMax, UserStruct.ByReference idBuffer,int[] nCounter);
} 在按钮过程中做如下
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
UserStruct idBuffer = new UserStruct();
idBuffer.Address=0;
idBuffer.Length=0;
idBuffer.num[0][0]=(byte)0x00; // 这地方没有把数组全面初始化不知道影响否??? int nCounter[]={0};
int nMax=10; apiReturn=RFSAPIV2.INSTANCE.ReadID(hScanner[0], nMax, idBuffer, nCounter);
} 做语法检查时,,提示上面的函数调用部分的红色字体,即第三个参数 错误。
“
无法将 接口 desktopapplication2.DesktopApplication2View.RFSAPIV2 中的 方法 ReadID 应用于 long,int,desktopapplication2.DesktopApplication2View.UserStruct.ByReference,int[](long,int,desktopapplication2.DesktopApplication2View.UserStruct,int[])
--
(按 Alt-Enter 组合键可显示提示)
”
请指导一下 ,谢谢。
指导解决问题后,送1000分,外加3合1 ARM开发板一块(邮资自付)
本人结贴即使,可参加近几天的结贴情况,已经前后送出了1000分了,就这个问题
解决方案 »
- Socket 异常!很简单 大家帮忙找找错!
- netbeans打包问题。
- 将"a.b.c.d"中的点符号转换成反斜杠
- 接口声明实例?
- 【UML的问题】在通讯图(就是2.0的协作图里)如何对if-else建模?
- 字符串替换问题,初学者,希望帮一下忙来看一看
- 请问大家有没有关于java的图形设计和swing设计的比较好的网站?
- 各位JAVA的大哥,帮一帮小弟呀!!!!!!!!!!
- 刚刚学习java,怎么配置其环境?
- 请问在java中有没有一个用来显示字符串用的二维表的类呀,象JTable一样,不过要带滚动条的.
- 求jna调用so可以返回struct的实例。不甚感激!我的老是报jvm crash,请高手指点!
- 关于SWT Win32 Extension
* 此处可供大家参考,有什么不对的地方请大家指点。
*/public class FNHFD1008 { /**
* 打开指定串口、地址的读写器,并加载动态链接库。 在对读写器进行操作前必须调用此方法。在应用程序退出前需调用StopComm方法。
* @param Port 串口号
* USB串口号为1000, 0 表示com1, 1表示串口2, 依次类推,最大可到9表示com10
* @return
* 0:成功
* -1 加载动态库失败,
* 其他值表示失败
*/
public native int OpenComm(int Port);
/**
* 关闭串口,释放动态库资源
* @return
* 1:成功
* 其他值表示失败
*/
public native int StopComm();
/**
* 读卡片的序列号
* @return Tag UID
*/
public native String ReadUID(); /**
* 读取卡片上指定Block的数据
* @param keyA 密钥
* @param blockNum 块号
* @return 块数据
* 如果密钥错,返回"ERROR:readBlockFun failed!ret:4"
*/
public native String ReadBlock(String keyA, int blockNum); /**
* 写卡片上指定Block的数据
* @param keyA 密钥
* @param blockNum 块号
* @param data 块数据 必须是16字节的16进制数据,eg:2009050720093C0A000000000000FF20
* @return
* 如果密钥错,返回"ERROR:readBlockFun failed!ret:4"
*/
public native String WriteBlock(String keyA, int blockNum,String data);
/**
* 加载JNI动态链接库
*/
static {
String libName = "FNHFD1008Dll"; //加载FNHFD1008Dll.dll
try {
System.loadLibrary(libName);
System.out.println("Load Dll Success! Dll:" + libName);
} catch (UnsatisfiedLinkError err) {
System.out.println("Load Dll Error!dllName:" + libName);
}
} public static void main(String[] args) {
int ret=0;
FNHFD1008 fn = new FNHFD1008();
ret = fn.OpenComm(1000);
System.out.println("HFD1008:OpenComm ret:" + ret );
String uid = fn.ReadUID();
System.out.println("HFD1008:ReadUID ret:" + uid );
String block = fn.ReadBlock("ffffffffffff", 4);
System.out.println("HFD1008:ReadBlock ret:[" + block + "]");
//
String retStatus = fn.WriteBlock("ffffffffffff", 5, "00000000000000000000000031322E44");
System.out.println("HFD1008:WriteBlock ret:[" + retStatus + "]");
block = fn.ReadBlock("ffffffffffff", 5);//123456789abc
System.out.println("HFD1008:ReadBlock ret:[" + block + "]");
ret = fn.StopComm();
System.out.println("HFD1008:StopComm ret:" + ret );
}}
public static interface RFSAPIV2 extends Library {
RFSAPIV2 INSTANCE = (RFSAPIV2)
Native.loadLibrary("RFSAPIV2",
RFSAPIV2.class);
int ReadLabelID(long hh,int nMax, UserStruct.ByReference idBuffer,int[] nCounter);
} 在按钮过程中做如下
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
UserStruct idBuffer = new UserStruct();
idBuffer.Address=0;
idBuffer.Length=0;
idBuffer.num[0][0]=(byte)0x00; // 这地方没有把数组全面初始化不知道影响否??? int nCounter[]={0};
int nMax=10; apiReturn=RFSAPIV2.INSTANCE.ReadID(hScanner[0], nMax, idBuffer, nCounter);
}
你列的两个函数,即声明时,和调用时,我自己贴代码时疏忽了,但这个没有影响
因为我工程代码里是一致的。 所以不存在这个不匹配的问题,要不语法检查就过不了。
我去玩了几天,刚回来来,高手们还是要指点指点啊,,, 10.1 前都有效
其实是一样的,因为对于结构体,在JNA中一般传参的时候都默认是引用,除非要传值的话就要实现这个借口:
public static class ByValue extends UserStruct implements Structure.ByValue { },其实楼主在声明函数时可以直接这样写:
int ReadLabelID(NativeLong hh,int nMax, UserStruct idBuffer,int[] nCounter);
你函数的第一个参数在c中声明是long型,但是在JNA中一定要用NativeLong这个长整型来代替个人一点观点,最近也在研究这个,不知道可不可行,楼主试试吧~~呵呵,有问题继续提
如果你的Struct实现Structure.ByReference接口,那么JNA认为你的Struct是一个指针。指向C语言的结构体。
如果你的Struct实现Structure.ByValue接口,那么JNA认为你的Struct是值类型,就是C语言的结构体。
如果你不实现这2个接口,那么就相当于你实现了Structure.ByReference接口。
既然实现了两个接口,那么JNA是不是已经认定你的Struct是值类型,是不是这和ReadLabelID中的定义冲突?
楼主有没有试过,去掉这两个接口的实现,或者保持这样,而结构体用值传递
// 设置返回值类型:
deviceInitialize.setRetVal(Type.INT);
// 设置参数
deviceInitialize.setParameter(1, 3132);
// 执行
deviceInitialize.invoke();
// 获取返回值
int dd = deviceInitialize.getRetValAsInt();