送500分,请教一个问题,JAVA调用DLL时参数传递的问题

时间:2022-08-29 21:09:43
typedef struct
{
int Address;
int Length;
byte num[8][30];
}ID   

ReadID(HANDLE hScanner,int nMax, ID *IDBuffer, int *nCounter);

上面是VC 的 DLL 事, 对结构和 一个函数的描述


下面是我在JAVA 中,用JNA 时的声明,主要参考网上的程序,也不知道对不对。
 
public 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 UserStruct.ByValue[][] num= new UserStruct.ByValue[8][30]; //  对比VC里的原型,不知这样是否可行
    
}

为了在按钮过程中调用,下面是接口里的声明:
ReadID(long hh,int nMax,  UserStruct.ByReference idBuffer,int[] nCounter);

函数里的第三个参数,红字部分,不知道是否正确。


最后在按钮里添加代码, 想调用这个函数,所以声明一个变量(结构变量)
看网上别人的程序,照搬改写如下:

  UserStruct.ByReference idBuffer =new UserStruct.ByReference();
  int nCounter[]={0};
  int nMax=10;
   
  apiReturn=RFSAPIV2.INSTANCE.ReadID(hScanner[0], nMax, idBuffer, nCounter);
  上面是被调用的函数, 参数一是另个函数调用成功后的句柄,这个没问题
  第二个参数也没问题
  第四个也应该没问题
  
  问题我觉得应该出在第三个参数上, 现在不知道如何整,请高手指点一下,非常感谢!


  我按上面的编译,执行,报错如下:
  “
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
  at java.lang.reflect.Array.getLength(Native Method)
  at com.sun.jna.Structure.getNativeSize(Structure.java:1057)
  at com.sun.jna.Structure.getNativeAlignment(Structure.java:1007)
  at com.sun.jna.Structure.getNativeAlignment(Structure.java:1032)
  at com.sun.jna.Structure.calculateSize(Structure.java:946)
  at com.sun.jna.Structure.allocateMemory(Structure.java:219)
  at com.sun.jna.Structure.ensureAllocated(Structure.java:211)
  at com.sun.jna.Structure.write(Structure.java:554)
  at com.sun.jna.Function.convertArgument(Function.java:410)
  at com.sun.jna.Function.invoke(Function.java:206)
  at com.sun.jna.Library$Handler.invoke(Library.java:204)
  at $Proxy0.ReadID(Unknown Source)   
 后面还有,没列出来


  链接设备和断开连接设备,那两个函数都没问题,说JNA方法是可行的
 现在的这个函数,感觉参数复杂了点。 

  哪位能够给个解决办法,500分,可以再加 呵呵,,困扰了好几天了。。。。
 
  有效时间10.1前吧 呵呵,,不是研发任务,只是自己觉得没事,自个玩的,现在玩不出来,挺郁闷的。
  相信这样的感觉大家都应该有过的
  
 

11 个解决方案

#1


路过,帮顶

#2


不懂,帮顶。。。

#3


友情帮顶了。周末人少呢

#4


路过,顶一个

#5


up!!

#6


typedef struct
{
int Address;
int Length;
byte num[8][30];
}ID   

这里面是byte num[8][30];类型

为啥java这边:public 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 UserStruct.ByValue[][] num= new UserStruct.ByValue[8][30]; // 对比VC里的原型,不知这样是否可行。
    
}



对应的是public UserStruct.ByValue[][] num= new UserStruct.ByValue[8][30]; 
ByValue是UserStruct的子类型,不是byte类型啊?类型没匹配?



只用过jnative调用过,jnative是用面向对象方式构造内存块,然后把值设到内存块中然后传参数过去,和jni有些不太一样。

#7


对应的是public UserStruct.ByValue[][] num= new UserStruct.ByValue[8][30];  
ByValue是UserStruct的子类型,不是byte类型啊?类型没匹配?


 回楼上的

  我尝试过很多中定义了,貌似都不可以呢,请指导一下 谢谢

 只要这个函数调用成功,送500分,外加 STM8, 3合一开发板一块,为使用过的,只是拆看看看而已

#8


public UserStruct.ByValue[][] num= new UserStruct.ByValue[8][30];
应该改成byte [][] num = new byte[8][30];  ????

#9


我参考的代码如下:


假设我们现在有这样一个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 组合键可显示提示)



请指导一下 ,谢谢。

#10


我也尝试,将结构的声明,放入接口的声明内(因为参考的实例,提到将结构声明添加到接口声明中),,但也不行。

#11


不懂 !帮顶!

#1


路过,帮顶

#2


不懂,帮顶。。。

#3


友情帮顶了。周末人少呢

#4


路过,顶一个

#5


up!!

#6


typedef struct
{
int Address;
int Length;
byte num[8][30];
}ID   

这里面是byte num[8][30];类型

为啥java这边:public 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 UserStruct.ByValue[][] num= new UserStruct.ByValue[8][30]; // 对比VC里的原型,不知这样是否可行。
    
}



对应的是public UserStruct.ByValue[][] num= new UserStruct.ByValue[8][30]; 
ByValue是UserStruct的子类型,不是byte类型啊?类型没匹配?



只用过jnative调用过,jnative是用面向对象方式构造内存块,然后把值设到内存块中然后传参数过去,和jni有些不太一样。

#7


对应的是public UserStruct.ByValue[][] num= new UserStruct.ByValue[8][30];  
ByValue是UserStruct的子类型,不是byte类型啊?类型没匹配?


 回楼上的

  我尝试过很多中定义了,貌似都不可以呢,请指导一下 谢谢

 只要这个函数调用成功,送500分,外加 STM8, 3合一开发板一块,为使用过的,只是拆看看看而已

#8


public UserStruct.ByValue[][] num= new UserStruct.ByValue[8][30];
应该改成byte [][] num = new byte[8][30];  ????

#9


我参考的代码如下:


假设我们现在有这样一个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 组合键可显示提示)



请指导一下 ,谢谢。

#10


我也尝试,将结构的声明,放入接口的声明内(因为参考的实例,提到将结构声明添加到接口声明中),,但也不行。

#11


不懂 !帮顶!