使用JNA的功能scanf [英] Function scanf with JNA
问题描述
我正在尝试将scanf
函数与JNA一起使用:
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);
}
}
我对此并不陌生,而且我还阅读了很多有关JNA的文章.但是我真的不知道如何使用它. printf
函数可以正常工作.
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.
Java运行时环境检测到致命错误:
A fatal error has been detected by the Java Runtime Environment:
EXCEPTION_ACCESS_VIOLATION(0xc0000005)at pc = 0x000007fefe531435, pid = 10168,tid = 2964
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000007fefe531435, pid=10168, tid=2964
JRE版本:7.0_03-b05 Java VM:Java HotSpot(TM)64位服务器VM (22.1-b02混合模式Windows-amd64压缩的oops)问题框架: C [msvcrt.dll + 0x61435]
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]
无法写入核心转储.默认情况下,不启用小型转储 Windows客户端版本
Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
包含更多信息的错误报告文件另存为: ***** \ URC Lab \ hs_err_pid10168.log
An error report file with more information is saved as: *****\URC Lab\hs_err_pid10168.log
如果您要提交错误报告,请访问:
http://bugreport.sun.com/bugreport/crash.jsp
发生崩溃
Java虚拟机之外的本机代码.看到有问题的框架
有关在哪里报告该错误.
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.
程序输出:
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?
推荐答案
仔细阅读 scanf
.每个varargs参数都必须是指向可以将扫描项写入其中的内存的地址(即指针).
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
是不可变的对象.那意味着你不能写它.
Java String
is an immutable object. That means you can't write to it.
可写缓冲区包括原始数组(例如byte[]
),JNA Memory
或NIO缓冲区.在这种情况下,我建议使用足够大的Memory
,然后使用其
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.
如@Gary所建议的示例:
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");
}
}
这篇关于使用JNA的功能scanf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!