C stdlib函数的Java等效项

时间:2018-09-10 14:59:05

标签: java c java-native-interface jna

我想不出更好的头衔了。我试图找出从C的stdlib访问方法的最佳方法(在效率和代码明智的情况下)。为此的背景是,我试图在Java中获得mbstowcs的功能。程序。现在,在我的C代码中,我已经得到了:

const char* source = "D:\\test3\\source\\test.txt";
SName tmp1;
mbstowcs((wchar_t*)tmp1, source, 32 - 1);

SNametypedef unsigned short SName[32]的地方。稍后在代码tmp1中将其用作输入参数:

status = copyFilePath(tmp1, tmp2, info, &context);

我实质上想做的是使用JNA从Java端调用此copyFilePath。诀窍是我需要在Java程序中获得与C的mbstowcs相似的转换,因此以后我可以直接调用此函数而无需任何其他处理。就目前而言,在我看来,使用JNI时我将需要其他C代码,以便可以从stdlib获取mbstowcs的包装。

问题也是,Java是否有类似的方法可以将多字节字符串转换为宽字符字符串,就像在C / C ++中那样使它们全部工作?

2 个答案:

答案 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中执行此类操作的有效方法是使用ByteBufferCharBuffer对象,而CharsetDecoder顶部则填充前者。

但是,这些方法无法使用以零结尾的char*值。 Java的标准API不支持零终止。 (Java数组具有明确定义的长度。)

我的建议是不要将代码直接从C / C ++转换为Java。而是从头开始将其作为惯用的Java代码编写。 (而且,如果您真的需要 C或C ++代码的效率,请使用这些语言!)

  

我实质上想做的是使用JNA从Java端调用此copyFilePath。诀窍在于,我需要在Java程序中获得与C的mbstowcs相似的转换,以便以后可以直接调用此函数而无需任何其他处理。

所以简单的方法是:

  1. 在本机代码方面进行Java可以应付的转换(例如byte[]String)。
  2. 通过JNA将byte[]String或其他任何内容传递给Java。
  3. 让Java端对其进行缓存,这样就无需重复JNA调用了。

但是值得注意的是Knuth关于过早优化的建议。如果您经常越过Java /本机边界,以至于这种优化是值得的,则(IMO)应该重新考虑应用程序的更大设计;否则,您可能会遇到问题。例如为什么您的Java如此密集地调用本机代码(反之亦然)。