如何工作实现JNA回调?

时间:2014-01-23 06:34:02

标签: java jna

我正在使用jsf,spring和hibernate开发一个Web应用程序。这个应用程序是 与money.rediff.comfinance.yahoo.com等其他网站类似。我们公司有 与实时数据提供商达成协议。他提供了一个exe file 在安装时生成dll file,pdf列出了dll文件和其他方法 许可证文件。

我使用了依赖walker,发现方法用一些符号装饰。一世 我试图通过以下方式在JNA的帮助下调用dll文件的方法。

以下是我的代码,

DllImplementation .java

public interface CLibrary extends StdCallLibrary
    {
       CLibrary INSTANCE = (CLibrary) Native.loadLibrary("DeskApi", CLibrary.class, new 

HashMap() {{

              put("Initialise", "?

Initialise@CDeskApi@@QAEHPADPAVCDeskApiCallback@@@Z");
              put("GetQuote","?GetQuote@CDeskApi@@QAEHPADHKK@Z");
              put("DeleteQuote","?DeleteQuote@CDeskApi@@QAEHPADH@Z");
              put("VersionInfo","?VersionInfo@CDeskApi@@QAEHPAD@Z");

              //Other functions
              }});

    public int Initialise(String serialkey,CDeskApiCallback callBack);
    public int GetQuote(String symbol, int periodicity, long lasttimeupdate, long 

echo);
    public int DeleteQuote(String symbol, int periodicity);
    public int VersionInfo(String versionOut);

    }




    public static  void main(String argv[]) {

            try{

                CDeskApiCallback callback = new CDeskApiCallback();

                String key = "fsg@xxxxxxxxxxxxxxxxxxxxd24";

                int retValue = CLibrary.INSTANCE.Initialise(key,callback);

                System.out.println("Initialise () ="+retValue);  




             } catch (UnsatisfiedLinkError e) {

                 e.printStackTrace();
             }
        }
}

CDeskApiCallback.java

public class CDeskApiCallback {


    public  native int realtime_notify(String symbol, Pointer recent);
    public  native int quote_notify( String symbol, int interval, int nMaxSize, 

    Pointer quotes, long echo);

}

Quotation.java

public class Quotation  extends Structure implements Structure.ByReference{ 
    public NativeLong DateTime; // 8 byte
    public float   Price;
    public float   Open;
    public float   High;
    public float   Low;
    public float   Volume;
    public float   OpenInterest;

    public Quotation(){
       super();
       System.out.println("in Quotation()");
       read();
    }

}

RecentInfo.java

public class RecentInfo extends Structure  implements Structure.ByReference{

    public  float   fOpen;
    public  float   fHigh;
    public  float   fLow;
    public  float   fLast;
    public  float   fTradeVol;
    public  float   fTotalVol;
    public  float   fOpenInt;
    public  float   fPrev;
    public  float   fBid;
    public  float   fAsk;
    public  int     iBidSize;   
    public  int     iAskSize;
    public  NativeLong  DateTime;

    public RecentInfo(){
        super();
        read();
        }

}

为了在执行main方法时测试代码,我得到-1作为整数返回值。从软件提供商的pdf中可以看出它是错误的。我该如何实现回调机制。

我是JNA新功能的新手。任何线索或帮助都会非常明显。


修改

@manuell

首先感谢您的帮助。我按照建议进行了更改,但没有用。我粘贴了软件提供商提供的头文件。请建议......

#pragma once
//version 0.0 Beta 1
#define DAILY_PERIOD 24*60
#define MIN_PERIOD   1

#ifdef API_DLL 
#define METHOD_TYPE __declspec(dllexport)
#else
#define METHOD_TYPE __declspec(dllimport)
#endif
//data is provided in the struct below
struct Quotation {
                        unsigned long DateTime; // 8 byte
                        float   Price;
                        float   Open;
                        float   High;
                        float   Low;
                        float   Volume;
                        float   OpenInterest;                       
                 };

struct RecentInfo
{
    float   fOpen;
    float   fHigh;
    float   fLow;
    float   fLast;
    float   fTradeVol;
    float   fTotalVol;
    float   fOpenInt;
    float   fPrev;
    float   fBid;
    int     iBidSize;
    float   fAsk;
    int     iAskSize;
    unsigned long DateTime; // 8 byte   
};

//callback class which is to be implemented by the client application
class METHOD_TYPE CDeskApiCallback
{
    public:
        /*
        Description : Tick Update from the server for symbol requested
        Parameters  : 1. symbol of interest
                      2. Data, please note value -1 indicates no update.
        Return      : 0 in case of success and -1 in case of error  
        */  
    virtual int realtime_notify(const char* symbol, RecentInfo *pRecent)=0;
        /*
        Description : Vwap Update from the server for symbol requested
        Parameters  : 1. symbol of interest
                      2. update of interval requested
                      3. data size
                      4. data
                      5. user message
        Return      : 0 in case of success and -1 in case of error  
        */  
    virtual int quote_notify( const char* symbol, int interval, int nMaxSize, Quotation *pQuotes, unsigned long echo)=0;    
};

//this is the control class from which requests are initiated.
class  METHOD_TYPE CDeskApi
{
public:
    CDeskApi(void);

        /*
    Description : Initiates a connection to NEST system
    Parameters  : 1. serialkey provided to implement the api
                  2. object of CDeskApiCallback implemented

    Return      : 0 in case of success and -1 in case of error  
        */  
    int Initialise(char *serialkey, CDeskApiCallback* callback);
        /*
        Description : Request data from the server
        Parameters  : 1. symbol of interest
                      2. intervals of 1 min, multiples of 1 min, DAILY_PERIOD in case of daily.
                      3. data to be retrieved from. in no of seconds since epoch
                      4. identifier, which is returned in the callback          
        Return      : 0 in case of success and -1 in case of error  
        */  

    int GetQuote(char * symbol, int periodicity, unsigned long lasttimeupdate, unsigned long echo);
        /*
        Description : Delete a Prior Request to the server
        Parameters  : 1. symbol of interest
                      2. interval, send -1 to delete all requested information of the symbol 
        Return      : 0 in case of success and -1 in case of error  
        */  
    int DeleteQuote(char * symbol, int periodicity);
        /*
        Description : Delete a Prior Request to the server
        Parameters  : 1. symbol of interest
                      2. interval, send -1 to delete all requested information of the symbol 
        Return      : 0 in case of success and -1 in case of error  
        */  
    int VersionInfo(char * versionout);
    ~CDeskApi(void);
};

1 个答案:

答案 0 :(得分:2)

本机DLL是C ++版本,导出类。

这意味着,例如,Initialise方法是一种“*this”方法。

这也意味着回调参数(来自Initialize的第二个)应该是指向VTBL的指针(因为C ++ CDeskApiCallback类是抽象的)。

您可以使用Java Pointer类型处理这两个问题,但这将是棘手的黑客攻击。默认情况下,规则是明确的:您不能在C ++类上下文中使用JNA。

你有3个选择(加上棘手的选择):

  1. 尝试使用Bridj
  2. 尝试使用jnaerator
  3. 自己写一个C ++ Dll Wrapper并在JNA(或JNI)中使用它。
  4. 第三个涉及基本的C / C ++知识和Visual Studio(Express)环境。