为了账号安全,请及时绑定邮箱和手机立即绑定

C stdlib 函数的 Java 等效项

C stdlib 函数的 Java 等效项

收到一只叮咚 2021-09-12 16:09:49
我想不出更好的标题,所以就在这里。我试图找出从 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);我本质上想做的是copyFilePath使用 JNA 从 Java 端调用它。诀窍是我需要在 Java 程序中对 C 的 mbstowcs 进行类似的转换,以便稍后我可以直接调用此函数而无需任何额外处理。现在在我看来,在使用 JNI 时我需要额外的 C 代码,以便我可以从 stdlib 获得 mbstowcs 的包装器。问题还在于,Java 是否有任何类似的方法可以像在 C/C++ 中一样将多字节字符串转换为宽字符串以使其全部解决?
查看完整描述

2 回答

?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

不是回答问题,而是试图帮助解决问题。JNA 有com.sun.jna.WString. 如果您使用 WString 参数调用函数,它将在本机代码中显示为宽字符串。你只需要确保你有正确的编码。

而不是function.invoke(myString);它在本机端为您提供多字节字符串,只需使用function.invoke(new WString(myString));


查看完整回答
反对 回复 2021-09-12
?
隔江千里

TA贡献1906条经验 获得超10个赞

将字节转换为文本的简单自然方法是使用字符串构造函数;例如


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 进行类似的转换,以便稍后我可以直接调用此函数而无需任何额外处理。


所以简单的方法是:


在本机代码端转换为 Java 可以处理的内容(例如abyte[]或 a String)。

通过 JNA将byte[]orString或任何内容传递给 Java。

让 Java 端缓存它,以便不需要重复 JNA 调用。

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


查看完整回答
反对 回复 2021-09-12
  • 2 回答
  • 0 关注
  • 177 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信