Java C stdlib 函数的等价物
Java equivalents for C stdlib functions
我想不出更好的标题,所以就在这里。我试图找出从 C 的 stdlib 访问方法的最佳方式(在效率和代码清晰的情况下)。背景是我试图在 [ 中获得 mbstowcs 的功能=28=]程序。现在在我的 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 进行类似的转换,以便稍后我可以直接调用此函数而无需任何额外处理。现在在我看来,我需要额外的 C 代码来使用 JNI,这样我就可以从 stdlib 获得 mbstowcs 的包装器。
还有一个问题,是否有任何类似的方法可以让 Java 将多字节字符串转换为 wide-character 字符串,就像在 C/C++ 中一样,以便全部解决?
将字节转换为文本的简单自然方法是使用字符串构造函数;例如
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++ 代码的效率,请使用这些语言!)
What I am essentially trying to do is to call this copyFilePath from Java side using JNA. The trick is that I would need to get similar conversion to C's mbstowcs in Java program so later I could directly call this function without any additional processing.
所以简单的做法是:
- 在本机代码端转换为 Java 可以处理的内容(例如
byte[]
或 String
)。
- 通过 JNA 将
byte[]
或 String
或其他任何内容传递给 Java。
- 让 Java 端缓存它,这样 JNA 调用就不需要重复了。
但值得注意的是 Knuth 关于过早优化的建议。如果您经常跨越 Java / 本机边界,以至于这种优化是值得的,您应该(IMO)重新考虑应用程序的更大设计;例如为什么您的 Java 如此密集地调用本机代码(反之亦然)。
没有回答问题,而是试图帮助解决问题。 JNA 有 com.sun.jna.WString
。如果您调用带有 WString 参数的函数,它将在本机代码中显示为宽字符串。您只需确保您的编码正确。
而不是 function.invoke(myString);
在本机端为您提供多字节字符串,只需使用 function.invoke(new WString(myString));
我想不出更好的标题,所以就在这里。我试图找出从 C 的 stdlib 访问方法的最佳方式(在效率和代码清晰的情况下)。背景是我试图在 [ 中获得 mbstowcs 的功能=28=]程序。现在在我的 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 进行类似的转换,以便稍后我可以直接调用此函数而无需任何额外处理。现在在我看来,我需要额外的 C 代码来使用 JNI,这样我就可以从 stdlib 获得 mbstowcs 的包装器。
还有一个问题,是否有任何类似的方法可以让 Java 将多字节字符串转换为 wide-character 字符串,就像在 C/C++ 中一样,以便全部解决?
将字节转换为文本的简单自然方法是使用字符串构造函数;例如
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++ 代码的效率,请使用这些语言!)
What I am essentially trying to do is to call this copyFilePath from Java side using JNA. The trick is that I would need to get similar conversion to C's mbstowcs in Java program so later I could directly call this function without any additional processing.
所以简单的做法是:
- 在本机代码端转换为 Java 可以处理的内容(例如
byte[]
或String
)。 - 通过 JNA 将
byte[]
或String
或其他任何内容传递给 Java。 - 让 Java 端缓存它,这样 JNA 调用就不需要重复了。
但值得注意的是 Knuth 关于过早优化的建议。如果您经常跨越 Java / 本机边界,以至于这种优化是值得的,您应该(IMO)重新考虑应用程序的更大设计;例如为什么您的 Java 如此密集地调用本机代码(反之亦然)。
没有回答问题,而是试图帮助解决问题。 JNA 有 com.sun.jna.WString
。如果您调用带有 WString 参数的函数,它将在本机代码中显示为宽字符串。您只需确保您的编码正确。
而不是 function.invoke(myString);
在本机端为您提供多字节字符串,只需使用 function.invoke(new WString(myString));