简体   繁体   中英

Mapping c++ function with JNA

I have a problem trying to map this c++ function with JNA.

https://www.inventcom.net/fanuc-focas-library/program/cnc_rdexecprog

FWLIBAPI short WINAPI cnc_rdexecprog(unsigned short FlibHndl, unsigned short *length, short *blknum, char *data);

I tried with these mappings in java but dont work:

short cnc_rdexecprog(short FlibHndl, ShortByReference length, ShortByReference blknum, String data);
short cnc_rdexecprog(short FlibHndl, ShortByReference length, ShortByReference blknum, Pointer data);
short cnc_rdexecprog(short FlibHndl, ShortByReference length, ShortByReference blknum, Memory data);

The first mapping works but return me the same String that I send, the second and third shows this error:

Exception in thread "AWT-EventQueue-0" java.lang.Error: Invalid memory access

I was able to get similar functions working thanks to this thread: Use C++ DLL from Java with JNA

I think that the problem are in the output parameter "char *data". How to map this function?

The char * type is expecting a buffer of bytes (characters in C).

Java's String type is immutable ( const char * ) so the native code can't modify it, as you've observed. The Pointer type would work but as you see from the error message, doesn't point to allocated memory. Memory also works (and extends Pointer ) but requires you to actually allocate the memory with your parameter. For example:

Memory buffer = new Memory(bufferSize);

You could pass buffer as either a Pointer or Memory to your method and it would work.

The problem here is determining what the value of bufferSize should be. This is where the API helpfully tells you:

length [ in/out ] Specify the address of the variable which shows the number of characters to be read. Set the number of characters to be read to this variable *length(length). After reading, the number of characters actually read is set in this variable *length(length) again.

You need to coordinate the size of your buffer and the length you pass in the second argument. Consult the documentation to see if there is any constant defining the max length of the string you expect, and use that. (Based on this example , it may be MAX_PROG_SIZE (1024*2), with an extra byte added for the null terminator. But you should verify this yourself.)

If that doesn't exist, a standard JNA idiom is:

  • Declare a size and pass it to the native function (length and allocated buffer should match)
  • Check for a result code indicating you didn't provide enough characters (probably EW_LENGTH (2))
  • Repeat with a larger buffer until the string fits.

Alternately you can start with a much larger value.

In all cases, remember to add 1 to the actual max string length to account for the null terminator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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