前两篇文章中大概说了下关于JAVA通过JNA机制调用DLL(c/c++),是项目中需要的一部分,后来因为种种原因,放弃不用了(翻译了6K多行啊,可惜了【么了,友情提醒一下,如果真的需要把一个大的c/c++代码转换过来(头文件),建议最好写一些 正则表达式来用程序翻译,之前翻译的是一个关于球机的代码,底层DLL写好了,需要翻译头文件,大概3k行左右,因为是头文件,所以翻译比较简单,如果是复杂的数据结构比如说set啦,map啦,这些其实我也不知道该如何翻译,项目中由于都是c写的,所以翻译方便些】)
上次没忘记了添加unsigned long long以及引用映射,刚好有人问一些基本数据类型之间的映射关系,就索性把剩下的一些补上吧。
下面这些是实践调试所得,如果有问题还希望大家批评指出
int*的映射:
C++代码如下:
extern "C" __declspec( dllexport )int & Add(int &a )
{
a=0xff;
printf("In C++: %d\n",a);
return a;
}
注意,引用和指针调用法是一模一样的:
JAVA中声明如下:
IntByReference Add(IntByReference first);
调用如下:
IntByReference xy_ref = new IntByReference();
IntByReference xy=TestJnaLib.INSTANCE.Add(xy_ref);
System.out.print(xy_ref.getValue()+" ");
输出如下:
255 In C++: 255
传参数的时候一定要用new出来,否则无法分配空间,取值的时候用另外的一个指针:
IntByReference xy_ref = new IntByReference();
IntByReference xy=null;//=new IntByReference();
xy=TestJnaLib.INSTANCE.Add(xy_ref);
System.out.println(xy.getValue());
System.out.println(xy_ref.getValue());
这样的输出是:
255
255
In C++: 255
关与long long64位类型的映射,其他的unsigned 都是8位,16位由32保存然后取后8位或者16位,所以想到用128位,但是传参的时候long long是一个基础变量,难不成用128位数组,好像也不行,但是这样想,反正都是64,无非是符号位的问题,先把数据取出来再说:
extern "C" __declspec( dllexport )long long Add(long long a )
{
a=0x8fffffffffffffff;
printf("In C++: %lld\n",a);
return a;
}
public static void main(String[] args) {
//System.out.print("sdfsadf\n");
long ss=10;
long res;
res=TestJnaLib.INSTANCE.Add(ss);
System.out.println(res);
System.out.println(ss);
}
输出结果为:
-8070450532247928833
10
In C++: -8070450532247928833
可以看到对于无符号是可行的,反正第一位也没用,下面看看unsigned long long 怎么处理:
extern "C" __declspec( dllexport )unsigned long long Add(unsigned long long a )
{
a=0x8fffffffffffffff;
printf("In C++: %llu\n",a);
return a;
}
对于无符号变量,用long也能取回来,但是第一位被用作了符号位,谁让java不支持unsigned呢,那么对已基本变量已经没有比64更大的了,所以我们只能用java提供的BigInteger来处理:
public static void main(String[] args) {
long ss=10;
long res;
//IntByReference xy_ref = new IntByReference();
// IntByReference xy=null;//=new IntByReference();
res=TestJnaLib.INSTANCE.Add(ss);
BigInteger bi = new BigInteger
(Long.toHexString(res), 16);
System.out.println(Long.toHexString(res));
System.out.println(bi);
}
把返回的值用long变量来接收,然后转成16进制,在初始化BigInteger,然后,没有然后了,转了之后看看输出,就是我们要的结果了:
8fffffffffffffff
10376293541461622783
In C++: 10376293541461622783
至于如果取回来还需要进行四则运算的话,依然需要用到这个BigInteger类。