java的scanf,使用JNA的功能scanf

I'm trying to use the scanf 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 out how to use it. The printf 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:

http://bugreport.sun.com/bugreport/crash.jsp 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?

解决方案

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.

An example, as @Gary suggested:

import com.sun.jna.Library;

import com.sun.jna.Native;

import com.sun.jna.Platform;

import com.sun.jna.Pointer;

public interface JNAApiInterface extends Library {

JNAApiInterface INSTANCE = (JNAApiInterface) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), JNAApiInterface.class);

Pointer __iob_func();

int sizeOfFileStructure = Platform.is64Bit() ? 48 : 32;

Pointer stdout = JNAApiInterface.INSTANCE.__iob_func().share(sizeOfFileStructure);

void printf(String format, Object... args);

int sprintf(byte[] buffer, String format, Object... args);

int scanf(String format, Object... args);

int fflush (Pointer stream);

int puts(String format) ;

int fprintf(Pointer stream, String format, Object...args) ;

void setbuf(Pointer stream, String buffer) ;

}

import com.sun.jna.Memory;

import com.sun.jna.platform.win32.Kernel32;

public class JNABucket {

public static void main(String args[]) {

JNAApiInterface jnaLib = JNAApiInterface.INSTANCE;

Kernel32 klib = Kernel32.INSTANCE;

Memory userName = new Memory(256);

jnaLib.setbuf(jnaLib.stdout, null);

jnaLib.printf("Hello World");

for (int i = 0; i < args.length; i++) {

jnaLib.printf("\nArgument %d : %s", i, args[i]);

}

jnaLib.puts("\nPlease Enter Your Name:\n");

jnaLib.scanf("%s", userName);

jnaLib.printf("\nYour name is: %s", userName);

jnaLib.fprintf(jnaLib.stdout, "\nThis is a Test");

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值