unsigned char __stdcall pcdgetdevicenumber(unsigned char *devicenumber)
这种VC++里面的函数、用JNI实现的时候。数据类型怎么对应?

解决方案 »

  1.   

    用JNI怎么对应?问题有点表达不清,你是指java中的方法怎么映射到unsigned char __stdcall pcdgetdevicenumber(unsigned char *devicenumber)中去么?可以用javah生成相应的头文件,然后在头文件中函数的实现里调用你这里的pcdgetdevicenumber函数或者使用registerJniNative函数。
      

  2.   

    嗯。就是这个函数是现存的DLL里面的。我只会用javah生成头文件、生成之后怎么实现。怎么调用现存的DLL这个函数、不会、网上搜了些例子找这些总是有问题
      

  3.   


    用javah生成了相应的头文件以后,写一个cpp的程序包含这个头文件并实现头文件中的函数,要想调用dll中的函数,就得在cpp程序中包含dll的头文件,编译链接的时候指定此dll动态库的路径就好了,不知道你所说的"网上搜了些例子找这些总是有问题"是指出现哪些问题。
      

  4.   

    你帮我看看吧、以前没弄过这个。整的头大了、。本来就不会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
      

  5.   

    对JNI不是很了解,坐等大神回复。
    建议LZ去图书馆借点相关的书籍回来看看。
      

  6.   

    你这里已经通过
    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);
      

  7.   

    jni中关于数组的操作全在这个网址里:
    http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html#wp21732
      

  8.   

    char * str = env->GetByteArrayElements(jarray,NULL);这个报错的、
    'initializing' : cannot convert from 'signed char *' to 'char *'
    我这个typedef    char  (* getCardNum)(char[]);函数指针的申明没有问题吗?
      

  9.   

    从java传上来的jbyteArray只能转换成jbyte,它就是signed char* ,而你这里函数需要的是char *,所以肯定报错,不过我用gcc试了一下只有警告,你强转一下吧。dll的函数是:unsigned char __stdcall piccrequest(unsigned char *serial)
    所以函数指针应该为:typedef   unsigned char  (* getCardNum)(unsigned char[]);
    对应上
      

  10.   

    强制转化试试
    char * str = (char*) env->GetByteArrayElements(jarray,NULL);
      

  11.   

    这里“unsigned char __stdcall piccrequest(unsigned char *serial)”这样申明的话
    char * str = env->GetByteArrayElements(jarray,NULL);
    gnum(str); 这样传的str参数不是又对应不上了吗?
    java那端只是我随便申明的。我也不知道该是byte还是char
      

  12.   

    java端的给搞的跟dll需要的才行,dll需要unsigned char *,所以java需要jcharArray,数组中的类型为jchar,它在native类型为:unsigned short
      

  13.   

    一个头两个大、您反正熟悉、。就动动手把java端和C端的给写全点给我参考吧、按你说的。我java里面申明“public native short getCardSerialNum(short[] serial);”又整了半天也没整对
      

  14.   


    说的应该够清楚的吧,或者你先看我的博客里面关于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文档,给你参考参考,所有东西都在里面了