我想不出更好的头衔了。我试图找出从C的stdlib访问方法的最佳方法(在效率和代码明智的情况下)。为此的背景是,我试图在Java中获得mbstowcs的功能。程序。现在,在我的C代码中,我已经得到了:
const char* source = "D:\\test3\\source\\test.txt";
SName tmp1;
mbstowcs((wchar_t*)tmp1, source, 32 - 1);
SName
是typedef unsigned short SName[32]
的地方。稍后在代码tmp1
中将其用作输入参数:
status = copyFilePath(tmp1, tmp2, info, &context);
我实质上想做的是使用JNA从Java端调用此copyFilePath
。诀窍是我需要在Java程序中获得与C的mbstowcs相似的转换,因此以后我可以直接调用此函数而无需任何其他处理。就目前而言,在我看来,使用JNI时我将需要其他C代码,以便可以从stdlib获取mbstowcs的包装。
问题也是,Java是否有类似的方法可以将多字节字符串转换为宽字符字符串,就像在C / C ++中那样使它们全部工作?
答案 0 :(得分:4)
不回答问题,而是尝试帮助解决问题。 JNA有com.sun.jna.WString
。如果您调用带有WString参数的Function,它将在本机代码中显示为宽字符串。您只需要确保您具有正确的编码即可。
使用function.invoke(myString);
代替function.invoke(new WString(myString));
,在原生端为您提供多字节字符串
答案 1 :(得分:2)
将字节转换为文本的简单自然方法是使用字符串构造函数;例如
Charset charset = Charset.forName("UTF-8"); // for example, or use one of
// the predefined Charset constants in
// java.nio.charset.StandardCharsets
byte[] bytes = ...
String text = new String(bytes, charset);
在Java中执行此类操作的有效方法是使用ByteBuffer
和CharBuffer
对象,而CharsetDecoder
顶部则填充前者。
但是,这些方法无法使用以零结尾的char*
值。 Java的标准API不支持零终止。 (Java数组具有明确定义的长度。)
我的建议是不要将代码直接从C / C ++转换为Java。而是从头开始将其作为惯用的Java代码编写。 (而且,如果您真的需要 C或C ++代码的效率,请使用这些语言!)
我实质上想做的是使用JNA从Java端调用此copyFilePath。诀窍在于,我需要在Java程序中获得与C的mbstowcs相似的转换,以便以后可以直接调用此函数而无需任何其他处理。
所以简单的方法是:
byte[]
或String
)。byte[]
或String
或其他任何内容传递给Java。但是值得注意的是Knuth关于过早优化的建议。如果您经常越过Java /本机边界,以至于这种优化是值得的,则(IMO)应该重新考虑应用程序的更大设计;否则,您可能会遇到问题。例如为什么您的Java如此密集地调用本机代码(反之亦然)。