Java调用第三方so实现Key的读写实例(Linux)

现在有一个第三方的动态链接库文件mwic.so,现在需要在java中调用此so文件里的函数,故先要生成一个可供java调用的 so(SOTest),具体步骤如下:

1.在java中新建一个空的类SOTest,实现以下代码(假设本次只需要调用SOTest中的run函数):
public class SOTest {   
      static {
          System.load("/home/user/Linux/SOTest.so");
      }
      public native static int run();
      public static void main(String args[]){
          SOTest test = new SOTest();
          System.out.println("kkkkk"+test.run());
      }
}

2.编译刚刚的类,得到.class文件,之后用javah生成头文件(如果不能直接javah SOTest,可以在终端可以先cd进jdk/bin目录下,之后把SOTest.class文件放在该目录下,直接运行javah SOTest)

3.使用c++的开发工具(我这里使用的是geany)新建一个cpp文件SOTest.cpp,并把刚刚得到的SOTest.h文件放到该目录下,并实现cpp里的代码
SOTest.h文件代码:
//注意要把“#include ” 该成“#include "jni.h"”
#include "jni.h"
/* Header for class SOTest */

#ifndef _Included_SOTest
#define _Included_SOTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     SOTest
* Method:    run
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_SOTest_run
(JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

SOTest.cpp代码:
#include
#include
#include
#include "SOTest.h"
#include
#include

JNIEXPORT jint JNICALL Java_SOTest_run
(JNIEnv * env, jclass obj)
{
int devid=0;
int result;
bool tag=false;
std::cout<<"aaaaa";
int a=38400;
   std::cout<<"===============初始化,获得设备编号================/n";
   void* handle = dlopen("/home/user/Linux/mwic.so",RTLD_LAZY);
   typedef int (*auto_init)(char*,int);
   dlerror();
   auto_init AutoInit = (auto_init) dlsym(handle,"auto_init");
   const char *dlsym_error = dlerror();
   if(dlsym_error){
    //cerr<<"can't load symbol.."<    dlclose(handle);
    return -1;
   }
   devid=AutoInit("/home/user/Linux/star500x",38400);
   if(devid>0)
   {
    std::cout<<"success!/n";
   }else
   {
    std::cout<<"fail!/n";
   }
   std::cout<<"devid="<   std::cout<<"===============检查是否有卡================/n";
   typedef int (*get_status)(int,int *);
   dlerror();
   get_status GetStatus = (get_status) dlsym(handle,"get_status");
   dlsym_error = dlerror();
   if(dlsym_error){
    dlclose(handle);
    return -1;
   }
   int status;
   GetStatus(devid,&status);
   if(status==1)
   {
    std::cout<<"has card!/n";
   }else
   {
    std::cout<<"no card!/n";
   }
   std::cout<<"===============检查是否4442卡=================/n";
   typedef int (*chk_4442)(int);
   dlerror();
   chk_4442 Chk4442 = (chk_4442) dlsym(handle,"chk_4442");
   dlsym_error = dlerror();
   if(dlsym_error){
    //cerr<<"can't load symbol.."<    dlclose(handle);
    return -1;
   }
   result = Chk4442(devid);
   if(result==0)
   {
    std::cout<<"4442 card!/n";
   }else
   {
    std::cout<<"not 4442 catrd!/n";
   }
   std::cout<<"===============读出错计数器====================/n";
  
   typedef int (*rsct_4442)(int,int *);
   dlerror();
   rsct_4442 Rsct4442 = (rsct_4442) dlsym(handle,"rsct_4442");
   dlsym_error = dlerror();
   if(dlsym_error){
    dlclose(handle);
    return -1;
   }
   int counter;
   result=Rsct4442(devid,&counter);
   if(result>=0)
   {
    std::cout<<"count="<    if(counter>1)
    {
     tag=true;
    }
   }else
   {
    std::cout<<"error!/n";
   }
   if(tag==true)
   {
    std::cout<<"================校验密码=======================/n";
    typedef int (*csc_4442)(int,int,unsigned char *);
    dlerror();
    csc_4442 Csc4442 = (csc_4442) dlsym(handle,"csc_4442");
    dlsym_error = dlerror();
    if(dlsym_error){
     dlclose(handle);
     return -1;
    }
   
    unsigned char databuff[20];   
    unsigned char kk[20];
    memcpy(databuff,"/x11/x11/x11",3);
    memcpy(kk,"/xff/xff/xff",3);
    for(int k=0;k<3;k++)
    {
     std::cout<    }   
    std::cout<<"databuff="<    std::cout<<"kk="<    //unsigned char * data1="0xffffff";
    //data1 = (unsigned char*)(const_cast(""));
   
    result = Csc4442(devid,3,databuff);
    //t=&tt;
    if(result==0)
    {
     std::cout<<"password ok!/n";
    }else
    {
     std::cout<<"password wrong!/n";
    }
    std::cout<<"================写密码:111111==============/n";
    typedef int (*wsc_4442)(int,int,unsigned char *);
    dlerror();
    wsc_4442 Wsc4442 = (wsc_4442) dlsym(handle,"wsc_4442");
    dlsym_error = dlerror();
    if(dlsym_error){
     dlclose(handle);
     return -1;
    }
    unsigned char password[3];
    memcpy(password,"/x11/x11/x11",3);
    std::cout<<"set password to:"<    result=Wsc4442(devid,3,password);
    if(result==0)
    {
     std::cout<<"set password success!/n";
     std::cout<<"password="<    }else
    {
     std::cout<<"set password faild!/n";
    }
   
   
    std::cout<<"================读密码=====================/n";
    typedef int (*rsc_4442)(int,int,unsigned char *);
    dlerror();
    rsc_4442 Rsc4442 = (rsc_4442) dlsym(handle,"rsc_4442");
    dlsym_error = dlerror();
    if(dlsym_error){
     dlclose(handle);
     return -1;
    }
    //unsigned char * password=(unsigned char*)(const_cast("aaa"));
    //unsigned char * password;
    //unsigned char password[20];
   
    memcpy(password,"aaa",3);
    //password="aaaa";
    std::cout<    result=Rsc4442(devid,3,password);
    if(result==0)
    {
     std::cout<<"read password success!/n";
     printf("password=%s/n",password);
    }else
    {
     std::cout<<"read password fiald!/n";
    }
    std::cout<<"================write data====================/n";
    typedef int (*swr_4442)(int,int,int,unsigned char *);
    dlerror();
    swr_4442 Swr4442 = (swr_4442) dlsym(handle,"swr_4442");
    dlsym_error = dlerror();
    if(dlsym_error){
     dlclose(handle);
     return -1;
    }
    unsigned char data[2000];
    memcpy(data,"123456",256-32);
    result=Swr4442(devid,32,256-32,data);
    if(result==0)
    {
     std::cout<<"write data success!/n";
     std::cout<<"data="<    }else{
     std::cout<<"write data error!/n";
    }
    std::cout<<"================read data====================/n";
    typedef int (*srd_4442)(int,int,int,unsigned char *);
    dlerror();
    srd_4442 Srd4442 = (srd_4442) dlsym(handle,"srd_4442");
    dlsym_error = dlerror();
    if(dlsym_error){
     dlclose(handle);
     return -1;
    }
    unsigned char dataread[2000];
    result=Srd4442(devid,32,256-32,dataread);
    if(result==0)
    {
     printf("read data success!/n");
     printf("data=%s/n",dataread);
    }else
    {
     printf("read data error!/n");
    }
   

   }else
   {
    std::cout<<"can not go on!/n";
   }
   return 0;
}

4.把jdk/include目录下的jni.h和linux目录下的jni_md.h目录复制到SOTest.cpp同级目录下
   在geany中设置编译和生成参数
    编译:g++ -Wall -c "%f" -o "%e"
   生成:g++ -wl,--kill-at -shared -o "%e".so "%f"
   之后编译生成SOTest.so文件

5.把SOTest.so文件放到之前java代码中指定的地方("/home/user/Linux),运行程序,ok!

 

转: http://www.pczpg.com/a/2010/0421/6114.html

你可能感兴趣的:(Linux,技术)