2013-03-11 78 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;