tr4pt tr4pt - 1 year ago 116
Java Question

Function scanf with JNA

I'm trying to use the

function with JNA:

package importDLLs;

import com.sun.jna.Library;
import com.sun.jna.Native;

public class JNATest {

public interface CLibrary extends Library {
CLibrary clib = (CLibrary) Native.loadLibrary("msvcrt", CLibrary.class);

void printf(String format, Object... args);
int sprintf(byte[] speicher, String format, Object...args);
int scanf (String format, Object... args1);

public static void main(String[] args) {
CLibrary.clib.printf("Hello World");
String test= null;
args = new String[2];
args[0]="This is a test";
args[1]="and another one";
for ( int i = 0; i < args.length; i++ ){
CLibrary.clib.printf( "\nArgument %d : %s",i, args[ i ] );

CLibrary.clib.printf("\nBitte Namen eingeben");
CLibrary.clib.scanf("%s", test);
CLibrary.clib.printf("\nyour name is %s",test);

I'm new to this and I also read a lot about JNA. But I can't really figure it out how to use it. The
function works without problems.

This is the error I get, when I start it and after I wrote something to the console.

A fatal error has been detected by the Java Runtime Environment:

EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000007fefe531435,
pid=10168, tid=2964

JRE version: 7.0_03-b05 Java VM: Java HotSpot(TM) 64-Bit Server VM
(22.1-b02 mixed mode windows-amd64 compressed oops) Problematic frame:
C [msvcrt.dll+0x61435]

Failed to write core dump. Minidumps are not enabled by default on
client versions of Windows

An error report file with more information is saved as:
*****\URC Lab\hs_err_pid10168.log

If you would like to submit a bug report, please visit:
The crash happened
outside the Java Virtual Machine in native code. See problematic frame
for where to report the bug.

Program output:

Hello World
Argument 0 : This is a test
Argument 1 : and another one
your name is

Why do I get the error, and how can I fix it?

Answer Source

Read carefully the man page for scanf. Each varargs argument must be the address (i.e. a pointer) to memory where the scanned item may be written.

Java String is an immutable object. That means you can't write to it.

Writable buffers include primitive arrays (e.g. byte[]), JNA Memory, or an NIO buffer. In this case I'd recommend using Memory of sufficient size, then use its getString() method to extract the native NUL-terminated C string as a Java String.

For scanning other types, JNA provides ByReference and its subclasses, which provides the functionality of the common native &var notation.