java byreference,PointerByReference不返回值

本文探讨了如何使用JNA从Java调用C++函数,涉及使用`PointerByReference`处理字符串输入和输出参数。作者分享了遇到的问题,即`PointerByReference`在调用后变为null,通过代码实例和解决方法,帮助读者理解JNA中内存管理的要点。
摘要由CSDN通过智能技术生成

I'm trying to call a C++ function from Java via JNA. I want to pass in a string, and get a string back. This is done by using an in parameter and an out parameter. I use PointerByReference to represent the char** out parameter. The call to C++ works, but the PointerByReference is null after the call.

I based my code on the PointerByReference docs. Any ideas what I'm doing wrong?

I've added print statements to the C++ to make sure it's not not setting the pointer to null, and it's definitely not. So some in my use of JNA must be wrong. But what?

C++ code

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 code

Which is called by java like so:

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;

}

}

Stdout

And when I call it, I get results like this:

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()

I've tried to keep it minimal, and indeed there is not a lot going on.

I've tested with JNA versions 3.4 and 3.5

解决方案

Instead of allocating a new pointer for your length "return", you need to write to the existing pointer, e.g.

*outputLength = strlen(results) + 1;

You also need to write to the the buffer pointer that was given, rather than just assigning a new value to your local arg:

*output = results;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值