2013-03-11 77 views
3

我想通過JNA從Java調用C++函數。我想傳入一個字符串,並返回一個字符串。這是通過使用in參數和out參數完成的。我使用PointerByReference來表示char**輸出參數。對C++的調用有效,但PointerByReference在調用後爲空。PointerByReference不返回值

我根據我的代碼PointerByReference文檔。任何想法我做錯了什麼?

我已經向C++添加了打印語句,以確保它不會將指針設置爲null,而且絕對不是。所以我使用JNA的一些人一定是錯的。但是什麼?

C++代碼

void processRequest(char* input, char** output, int* outputLength) 
{ 

    // Variable output size from processInput 

    std::string sOutput = processInput(input); 


    char* results = new char[sOutput.length() + 1]; 

    strncpy(results, sOutput.c_str(), sOutput.length()); 

    results[sOutput.length()] = '\0'; 


    output = &results; 

    outputLength = new int(strlen(results) + 1); 

} 

Java代碼

這是由Java的稱爲像這樣:

public class RunRequestT1 { 
    private static final Logger log = LoggerFactory.getLogger(MyLibWrapperImpl.class); 

    static boolean envVarsSetupDone = false; 

    static interface MyLib extends Library { 

     MyLib INSTANCE = (MyLib) Native.loadLibrary("N:\\sys1\\sys1_dist\\MyLib\\MyLib9.8.Q.P3.G15.T\\bin\\MyLib.dll", MyLib.class); 

     public void processRequest(String request, PointerByReference bufp, IntByReference lenp); 

     public void clearMemoryPtr(PointerByReference bufp, IntByReference lenp); 
    } 

    public static void main(String[] args) throws IOException { 

     System.out.println("sys1: Reading request"); 
     String request = FileUtils.readFileToString(new File("C:\\dev\\prj\\single-request.xml"), "UTF-8"); 

     System.out.println("sys1: Pricing request"); 
     String response = processRequest(request); 

     System.out.println(response); 

    } 

    public static String processRequest(String request) { 

     System.out.println("sys1: prepare args"); 
     // code based on https://github.com/twall/jna/blob/master/www/ByRefArguments.md 
     PointerByReference bufp = new PointerByReference(); 
     IntByReference lenp = new IntByReference(); 

     System.out.println("sys1: making call"); 
     MyLib.INSTANCE.processRequest(request, bufp, lenp); 

     System.out.println("reading response"); 
     System.out.println("bufp: " + bufp.getValue()); 
     System.out.println("lenp: " + lenp.getValue()); 
     Pointer p = bufp.getValue(); 
     byte[] buffer = p.getByteArray(0, lenp.getValue()); 
     String response = Native.toString(buffer); 
     //String response = p.getString(0); 

     // de-allocate memory buffer 
     System.out.println("cleaning memory"); 
     MyLib.INSTANCE.clearMemoryPtr(bufp, lenp); 
     return response; 
    } 
} 

標準輸出

當我調用它,我得到的結果是這樣的:

sys1: Reading request 
sys1: Pricing request 
sys1: prepare args 
sys1: making call 
reading response 
bufp: null 
lenp: 0 
Exception in thread "main" java.lang.NullPointerException 
    at com.calyon.gcm.MyLibwrapper.main.RunRequestT1.priceRequest() 
    at com.calyon.gcm.MyLibwrapper.main.RunRequestT1.main() 

我試圖保持最小的,確實沒有很多事情。

我已經與JNA版本測試,3.4和3.5

+0

相反JNA的,你可以考慮使用[JavaCPP] (http://code.google.com/p/javacpp/),它可以直接調用C++函數。 – 2013-03-11 13:26:14

回答

3

而不是分配你的長度「迴歸」的新指針,你需要寫現有的指針,例如

*outputLength = strlen(results) + 1; 

您還需要寫入該被賦予了緩衝區指針,而不是僅僅分配一個新的值到本地ARG:

*output = results;