简体   繁体   English

如何工作实现JNA回调?

[英]how to work implement JNA callback?

I am developing a web application using jsf, spring and hibernate. 我正在使用jsf,spring和hibernate开发一个Web应用程序。 This application is similar to other web sites like money.rediff.com and finance.yahoo.com . 此应用程序类似于money.rediff.comfinance.yahoo.com等其他网站。 Our company has made a deal with a realtime data provider. 我们公司已与实时数据提供商达成协议。 He provided a exe file which on installing generates a dll file , pdf listing the methods of dll file and other license documents. 他提供了一个exe file ,在安装时会生成一个dll file ,pdf列出了dll文件的方法和其他许可证文件。

I used dependency walker and found that the methods are decorated with some symbols. 我使用了依赖walker,发现方法用一些符号装饰。 I am trying to call the methods of dll file with the help of JNA in the following way. 我试图通过以下方式在JNA的帮助下调用dll文件的方法。

Here are my codes, 这是我的代码,

DllImplementation .java 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 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 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 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();
        }

}

To test the code when I execute the main method I am getting a -1 as a integer return value. 为了在执行main方法时测试代码,我得到-1作为整数返回值。 From the pdf of software providers it indicates as an error. 从软件提供商的pdf中可以看出它是错误的。 How can i implement the callback mechanism. 我该如何实现回调机制。

I am new to JNA feature . 我是JNA新功能的新手。 Any clue or help will be highly appreciable. 任何线索或帮助都会非常值得注意。


Edit: 编辑:

@manuell @manuell

First of all thanks for the help. 首先感谢您的帮助。 I made the changes as advised but no use. 我按照建议进行了更改,但没有用。 I am pasting the header file given by the software provider. 我粘贴了软件提供商提供的头文件。 Please suggest... 请建议......

#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);
};

The native DLL is a C++ one, exporting classes. 本机DLL是C ++版本,导出类。

That means, for example, that the Initialise method is a " *this " method. 这意味着,例如,Initialise方法是一个“ *this ”方法。

That also means that the callback argument (second one from Initialize) should be a pointer to a VTBL (as the C++ CDeskApiCallback class is an abstract one). 这也意味着回调参数(来自Initialize的第二个)应该是指向VTBL的指针(因为C ++ CDeskApiCallback类是抽象的)。

You may be able to deals with the two problems using the Java Pointer type, but that will be tricky hacks. 您可以使用Java Pointer类型处理这两个问题,但这将是棘手的黑客攻击。 By default, the rules are clear: you can't use JNA in a C++ classes context. 默认情况下,规则是明确的:您不能在C ++类上下文中使用JNA。

You are left with 3 choices (plus the tricky one): 你有三个选择(加上棘手的一个):

  1. try to use Bridj 尝试使用Bridj
  2. try to use jnaerator 尝试使用jnaerator
  3. write yourself a C++ Dll Wrapper and use it from JNA (or JNI). 自己写一个C ++ Dll Wrapper并从JNA(或JNI)中使用它。

The third one involves basic C/C++ knowledge and a Visual Studio (Express) environnement. 第三个涉及基本的C / C ++知识和Visual Studio(Express)环境。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM