zoukankan      html  css  js  c++  java
  • 【转载】java调用C++写的DLL

    用java调用C++写的DLL一直以来都是一个比较麻烦但又很常见的问题。

    我们知道,使用 JNI 调用 .dll/.so 共享类库是非常非常麻烦和痛苦的。

    如果有一个现有的 .dll/.so 文件,如果使用 JNI 技术调用,我们首先需要另外使用 C 语言写一个 .dll/.so 共享库,使用 SUN 规定的数据结构替代 C 语言的数据结构,调用已有的   dll/so 中公布的函数。然后再在 Java 中载入这个适配器 dll/so ,再编写 Java   native 函数作为 dll 中函数的代理。经过 2 个繁琐的步骤才能在 Java 中调用本地代码。因此,很少有 Java 程序员愿意编写调用 dll/.so 库中的原生函数的 java 程序。这也使 Java 语言在客户端上乏善可陈。可以说 JNI 是 Java 的一大弱点。

    现在好了出现了一个JNA的武器,JNA框架是一个开源的 Java 框架,是 SUN 公司主导开发的,建立在经典的 JNI 的基础之上的一个框架。通过JNA能够很方便的调用C++写的DLL。

    先来一个Hello Word

    C++代码

     #ifndef DEMOC_H
     #define DEMOC_H
     #ifndef DLLDIR
     #define DLLDIR  extern "C"__declspec(dllexport)
     #endif
     typedef struct{
           char *m_sername;                   
           char *m_username;                 
           char *m_password;      
           WORD m_tranType;    
           HWND m_hChMsgWnd;  
           UINT m_nChmsgid;    
           int  m_sockType;       
           int  m_errormsg;  
           void (WINAPI *m_messagecallback)(LONG hHandle,char *wParam,int lParam);
           void *context;         
     }SERVER_UPDATEINFO;
     DLLDIR LONG __stdcall VSNET_ServerStart(char *m_url,SERVER_UPDATEINFO *m_pSerinfo,WORD wserport = 3000);
     #endif

    这是一个标准的C++头文件,在这个头文件中定义了一个函数VSNET_ServerStart,下面来分析一下这个头文件。首先看到在这个头文件中定义了一个宏DLLDIR,这个宏意义为导出编码为标准C(extern "C"),并且为declspec的。

    然后看到在头文件中还定义了一个结构体SERVER_UPDATEINFO,在SERVER_UPDATEINFO中具有以下几种数据类型:char类型指针,word类型,hwnd类型,uint,int,回调函数,void指针。

    这就是我们知道DLL中的所有信息。

    对了还有一个比较关键的地方,在C、C++中如果直接编译DLL,在DLL中导出的函数名是会在编译时被编译器修改掉,所以我们必须制定导出的函数名,这就需要在工程中定义一个def文件。

    def文件

     LIBRARY    "demoC"
     EXPORTS
     VSNET_ServerStart

    好了到此为止这就是我们所知道的所有DLL信息,一般这也是DLL组件会暴漏出来的所有信息。下面就来说明用JNA如何调用。

    首先我们先把DLL中的函数导出来,编程JAVA 的代码

     public interface CLibrary extends StdCallLibrary {
         VSNET_ServerStart
     }

    声明一个CLibrary的java接口,继承自JNA类库中的StdCallLibrary。OK已经导出来了,对了就这么简单。

    那么有些同学就问了,这个函数在C++的头文件中有一个LONG的返回值,而且还有参数啊?别急下面就来讲解。

    首先我们看到VSNET_ServerStart有一个LONG的返回值,LONG是C++中的数据类型,在java中是没有的,但是JNA已经为我们提供了这种类型叫做NativeLong。OK那么修改一下我们的JAVA代码

     public interface CLibrary extends StdCallLibrary {
         NativeLong VSNET_ServerStart
     }

    下面是JNA类型与C++类型的对比:

    接下来我们来看函数的参数如何处理。

    VSNET_ServerStart函数的参数为(char *m_url,SERVER_UPDATEINFO *m_pSerinfo,WORD wserport = 3000)。通过类型的对比我们知道char *=String,WORD=short。那个SERVER_UPDATEINFO这种结构体如何处理呢。

    在JNA中类库提供了一种Structure的类型专门处理结构体。下面我们用JAVA来描述一下这个结构体。

     public static class SERVER_UPDATEINFO extends Structure {
                      public String m_sername;
                      public String m_username;
                      public String m_password;
                      public short m_tranType;
                      public int m_hChMsgWnd;
                      public int m_nChmsgid;
                      public int m_sockType;
                      public int m_errormsg;
                      public ICallback fun;
         }

    对函数指针的处理

    对函数指针的处理

     public interface ICallback extends StdCallCallback{
         public abstract void fun(NativeLong hHandle,String wParam,int lParam);
     }
    

    OK我们成功的描述的结构体,下面再来修改我的java接口。

     public interface CLibrary extends StdCallLibrary {
         NativeLong VSNET_ServerStart(String m_url,SERVER_UPDATEINFO s,short sho)
     }
    

    到此就全部完成了DLL到JAVA的导出。下面来看如何使用。

     CLibrary INSTANCE = (CLibrary)Native.loadLibrary("demoC", CLibrary.class);
     ICallback C = new CallbackImp();
     CLibrary.SERVER_UPDATEINFO su = new CLibrary.SERVER_UPDATEINFO();
     su.m_sername = "sername";
     su.m_username = "username";
     ...
     su.fun = C;
     short sho = 3000;
     NativeLong nl = CLibrary.INSTANCE.VSNET_ServerStart("url",su,sho);
    

    OK,搞定。

    注意: 1、函数、结构体定义的名称必须和DLL中的一样。 2、函数结构体的参数顺序必须一样

  • 相关阅读:
    C#深入浅出 修饰符(二)
    HDU 5785 Interesting
    HDU 5783 Divide the Sequence
    HDU 5781 ATM Mechine
    UVA 714 Copying Books
    uva 1471 Defense Lines
    UVA 11134 Fabled Rooks
    UVA 11572 Unique Snowflakes
    UVA 11093 Just Finish it up
    UVA 10954 Add All
  • 原文地址:https://www.cnblogs.com/zhangxsh/p/3636023.html
Copyright © 2011-2022 走看看