JNI数据类型 unsigned char __stdcall pcdgetdevicenumber(unsigned char *devicenumber)这种VC++里面的函数、用JNI实现的时候。数据类型怎么对应? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 用JNI怎么对应?问题有点表达不清,你是指java中的方法怎么映射到unsigned char __stdcall pcdgetdevicenumber(unsigned char *devicenumber)中去么?可以用javah生成相应的头文件,然后在头文件中函数的实现里调用你这里的pcdgetdevicenumber函数或者使用registerJniNative函数。 嗯。就是这个函数是现存的DLL里面的。我只会用javah生成头文件、生成之后怎么实现。怎么调用现存的DLL这个函数、不会、网上搜了些例子找这些总是有问题 用javah生成了相应的头文件以后,写一个cpp的程序包含这个头文件并实现头文件中的函数,要想调用dll中的函数,就得在cpp程序中包含dll的头文件,编译链接的时候指定此dll动态库的路径就好了,不知道你所说的"网上搜了些例子找这些总是有问题"是指出现哪些问题。 你帮我看看吧、以前没弄过这个。整的头大了、。本来就不会C。unsigned char __stdcall piccrequest(unsigned char *serial){ unsigned char cRet; unsigned char pnsr[6]; cRet=checkM1(); if(cRet)return 24; cRet=M1Request(0x0A,pnsr); if(cRet)return 8; cRet=M1Select(pnsr); if(cRet)return 10; if(serial==NULL)return 0; else memcpy(serial,pnsr,4); return 0;}这是原DLL里面的一个函数、我在java里是这样申明的: /** * @return卡序列号 */ public native String getCardSerialNo(byte[] serial);对应的头文件里面的函数:/* * Class: com_szzc_jni_JniApi * Method: getCardSerialNo * Signature: ([B)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_szzc_jni_JniApi_getCardSerialNo (JNIEnv *, jobject, jbyteArray);对应的CPP里面的代码是:#include "stdafx.h"typedef char (* getCardNum)(char[]);HINSTANCE hModule=NULL;getCardNum gnum;BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ return TRUE;}JNIEXPORT jstring JNICALL Java_com_szzc_jni_JniApi_getCardSerialNo(JNIEnv * env, jobject obj, jbyteArray jarray){hModule=LoadLibrary("OUR_MIFARE.dll"); gnum = (getCardNum)GetProcAddress(hModule, "piccrequest");//...}指定了之后怎么去调用那个piccrequest函数。那些数据类型怎么转换就不知道了。也不知道申明错没。我在网上找了个例子。 /** * unsigned char __stdcall M1ReadSec(unsigned char cardtype, unsigned char * *pwd, unsigned char sector, unsigned char *buf, unsigned char timeout) */ public native int m1ReadSec(String cardType, String password, String sector, byte[] bufValue, int timeout);char有的声明成了int有的是string 对JNI不是很了解,坐等大神回复。建议LZ去图书馆借点相关的书籍回来看看。 你这里已经通过hModule=LoadLibrary("OUR_MIFARE.dll"); gnum = (getCardNum)GetProcAddress(hModule, "piccrequest");获得了dll动态链接库里函数的指针,这个函数需要传递一个char *进去,但是你这里从java层得到的是jbyteArray类型,因此你的问题本质就是:如何将一个jbyteArray类型转换成char*.使用此函数:jbyte *GetByteArrayElements(jbyteArray array, jboolean *isCopy);jbyte在头文件中被typedef了,其实它就是typedef signed char jbyte;所以你这里代码应该是:char * str = env->GetByteArrayElements(jarray,NULL);然后gnum(str); jni中关于数组的操作全在这个网址里:http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html#wp21732 char * str = env->GetByteArrayElements(jarray,NULL);这个报错的、'initializing' : cannot convert from 'signed char *' to 'char *'我这个typedef char (* getCardNum)(char[]);函数指针的申明没有问题吗? 从java传上来的jbyteArray只能转换成jbyte,它就是signed char* ,而你这里函数需要的是char *,所以肯定报错,不过我用gcc试了一下只有警告,你强转一下吧。dll的函数是:unsigned char __stdcall piccrequest(unsigned char *serial)所以函数指针应该为:typedef unsigned char (* getCardNum)(unsigned char[]);对应上 强制转化试试char * str = (char*) env->GetByteArrayElements(jarray,NULL); 这里“unsigned char __stdcall piccrequest(unsigned char *serial)”这样申明的话char * str = env->GetByteArrayElements(jarray,NULL);gnum(str); 这样传的str参数不是又对应不上了吗?java那端只是我随便申明的。我也不知道该是byte还是char java端的给搞的跟dll需要的才行,dll需要unsigned char *,所以java需要jcharArray,数组中的类型为jchar,它在native类型为:unsigned short 一个头两个大、您反正熟悉、。就动动手把java端和C端的给写全点给我参考吧、按你说的。我java里面申明“public native short getCardSerialNum(short[] serial);”又整了半天也没整对 说的应该够清楚的吧,或者你先看我的博客里面关于JNI的基础,虽然是Linux的,但windows的是一样。java中的方法修改为public native short getCardSerialNum(short[] serial);那么肯定需要再用javah工具编译出个头文件来,相应cpp的实现代码重新实现新的头文件中的函数,这个不难啊。http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/jniTOC.html这个是jni官方的API文档,给你参考参考,所有东西都在里面了 请人帮我解释下面一段代码(回帖即给分) java标签的键盘事件 StringBuffer str = new StringBuffer( 10 ) ;这里的10是str的容量,我要是想在这10个容量里写东西,要怎么写呢? JDK的环境变量在2K和XP下配制有区别么? java数据库连接问题求助,有源码,请高手帮改改。 请问怎么获得注册表中的ie可执行程序的路径 做JTREE遇到的问题~ 菜鸟问题:写好的 applet 怎么运行!?! 如何能在java重实现时间监视,定时运行 求教老手 关于动态代理Proxy.newProxyInstance方法参数的理解问题 关于java主线程的一道选择题
用javah生成了相应的头文件以后,写一个cpp的程序包含这个头文件并实现头文件中的函数,要想调用dll中的函数,就得在cpp程序中包含dll的头文件,编译链接的时候指定此dll动态库的路径就好了,不知道你所说的"网上搜了些例子找这些总是有问题"是指出现哪些问题。
{
unsigned char cRet;
unsigned char pnsr[6]; cRet=checkM1();
if(cRet)return 24; cRet=M1Request(0x0A,pnsr);
if(cRet)return 8;
cRet=M1Select(pnsr);
if(cRet)return 10;
if(serial==NULL)return 0;
else memcpy(serial,pnsr,4);
return 0;}
这是原DLL里面的一个函数、我在java里是这样申明的: /**
* @return卡序列号
*/
public native String getCardSerialNo(byte[] serial);
对应的头文件里面的函数:/*
* Class: com_szzc_jni_JniApi
* Method: getCardSerialNo
* Signature: ([B)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_szzc_jni_JniApi_getCardSerialNo
(JNIEnv *, jobject, jbyteArray);
对应的CPP里面的代码是:#include "stdafx.h"typedef char (* getCardNum)(char[]);
HINSTANCE hModule=NULL;
getCardNum gnum;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
JNIEXPORT jstring JNICALL Java_com_szzc_jni_JniApi_getCardSerialNo
(JNIEnv * env, jobject obj, jbyteArray jarray){
hModule=LoadLibrary("OUR_MIFARE.dll");
gnum = (getCardNum)GetProcAddress(hModule, "piccrequest");
//...
}指定了之后怎么去调用那个piccrequest函数。那些数据类型怎么转换就不知道了。也不知道申明错没。我在网上找了个例子。 /**
* unsigned char __stdcall M1ReadSec(unsigned char cardtype, unsigned char
* *pwd, unsigned char sector, unsigned char *buf, unsigned char timeout)
*/
public native int m1ReadSec(String cardType, String password,
String sector, byte[] bufValue, int timeout);char有的声明成了int有的是string
建议LZ去图书馆借点相关的书籍回来看看。
hModule=LoadLibrary("OUR_MIFARE.dll");
gnum = (getCardNum)GetProcAddress(hModule, "piccrequest");获得了dll动态链接库里函数的指针,这个函数需要传递一个char *进去,但是你这里从java层得到的是jbyteArray类型,因此你的问题本质就是:如何将一个jbyteArray类型转换成char*.使用此函数:
jbyte *GetByteArrayElements(jbyteArray array, jboolean *isCopy);
jbyte在头文件中被typedef了,其实它就是typedef signed char jbyte;所以你这里代码应该是:
char * str = env->GetByteArrayElements(jarray,NULL);
然后gnum(str);
http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html#wp21732
'initializing' : cannot convert from 'signed char *' to 'char *'
我这个typedef char (* getCardNum)(char[]);函数指针的申明没有问题吗?
所以函数指针应该为:typedef unsigned char (* getCardNum)(unsigned char[]);
对应上
char * str = (char*) env->GetByteArrayElements(jarray,NULL);
char * str = env->GetByteArrayElements(jarray,NULL);
gnum(str); 这样传的str参数不是又对应不上了吗?
java那端只是我随便申明的。我也不知道该是byte还是char
说的应该够清楚的吧,或者你先看我的博客里面关于JNI的基础,虽然是Linux的,但windows的是一样。
java中的方法修改为public native short getCardSerialNum(short[] serial);
那么肯定需要再用javah工具编译出个头文件来,相应cpp的实现代码重新实现新的头文件中的函数,这个不难啊。
http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/jniTOC.html这个是jni官方的API文档,给你参考参考,所有东西都在里面了