简体   繁体   English

C stdlib函数的Java等效项

[英]Java equivalents for C stdlib functions

I could not come up with better title so here it is. 我无法拿出更好的标题,所以在这里。 I am trying to figure out what would be the best way (in case of efficiency and clean code wise) of accessing methods from stdlib of C. Background for that is that I am trying to get a functionality of mbstowcs in Java program. 我试图找出从C的stdlib访问方法的最佳方法(在效率和代码明智的情况下)。为此的背景是,我试图在Java程序中获得mbstowcs的功能。 Right now in my C code I have got this: 现在,在我的C代码中,我得到了:

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

Where SName is typedef unsigned short SName[32] . 其中SNametypedef unsigned short SName[32] Later in code tmp1 is being used as an input argument: 稍后在代码tmp1中将其用作输入参数:

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

What I am essentially trying to do is to call this copyFilePath from Java side using JNA. 我本质上想做的是使用JNA从Java端调用此copyFilePath 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程序中获得与C的mbstowcs相似的转换,因此以后我可以直接调用此函数而无需任何其他处理。 For now it seems to me that I would be needing additional C code with in use of JNI so I could get a wrapper for mbstowcs from stdlib. 就目前而言,在我看来,在使用JNI时我将需要其他C代码,以便可以从stdlib获取mbstowcs的包装。

Question also is, are there any similiar ways for Java to convert multibyte string to wide-character string just like in C/C++ to get it all working out? 问题还在于,是否有Java可以像在C / C ++中一样将Java的多字节字符串转换为宽字符字符串的类似方法?

Not answering the question but trying to help with the problem. 不回答问题,而是尝试解决问题。 JNA has com.sun.jna.WString . JNA具有com.sun.jna.WString If you invoke a Function with a WString parameter, it will turn up as a wide string in the native code. 如果您调用带有WString参数的Function,它将在本机代码中显示为宽字符串。 You will only have to make sure that you've got the correct encoding. 您只需要确保您具有正确的编码即可。

Instead of function.invoke(myString); 代替function.invoke(myString); which gives you a multibyte string on the native side, just use function.invoke(new WString(myString)); 这将在本地提供一个多字节字符串,只需使用function.invoke(new WString(myString));

The simple natural way to convert bytes to a text would be use a string constructor; 将字节转换为文本的简单自然方法是使用字符串构造函数。 eg 例如

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);

The efficient way to do this kind of thing in Java is to use ByteBuffer and CharBuffer objects and a CharsetDecoder top fill the latter from the former. 在Java中执行此类操作的有效方法是使用ByteBufferCharBuffer对象,而CharsetDecoder则从前者填充后者。

But these approaches won't work you are using zero-terminated char* values. 但是,如果您使用的是零终止的char*值,那么这些方法将行不通。 Java's standard APIs don't support zero-termination. Java的标准API不支持零终止。 (A Java array has a well-defined length.) (Java数组具有明确定义的长度。)

My advice would be to not directly translate your code from C / C++ to Java. 我的建议是不要将代码直接从C / C ++转换为Java。 Instead, write it from scratch as idiomatic Java code. 而是从头开始将其作为惯用的Java代码编写。 (And if you really need the efficiency of C or C++ code, use those languages!) (如果您确实需要 C或C ++代码的效率,请使用这些语言!)

What I am essentially trying to do is to call this copyFilePath from Java side using JNA. 我本质上想做的是使用JNA从Java端调用此copyFilePath。 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程序中获得与C的mbstowcs相似的转换,因此以后我可以直接调用此函数而无需任何其他处理。

So the simple approach is: 因此,简单的方法是:

  1. Do the conversion to something that Java can cope with (a byte[] or a String for example) on the native code side. 在本机代码端转换为Java可以应付的东西(例如, byte[]String )。
  2. Pass the byte[] or String or whatever to Java via JNA. 通过JNA将byte[]String或其他内容传递给Java。
  3. Have the Java side cache it so that the JNA call doesn't need to be repeated. 让Java端对其进行缓存,这样就无需重复JNA调用。

But it it is worth noting Knuth's advice about premature optimization. 但是,值得注意的是Knuth关于过早优化的建议。 If you are crossing the Java / native boundary so often that this kind of optimization is going to be worthwhile, you should (IMO) reconsider the larger design of your application; 如果您经常越过Java /本机边界,以至于这种优化是值得的,则(IMO)应该重新考虑应用程序的更大设计;否则,您可能会遇到问题。 eg why your Java is calling native code so intensively (or vice versa). 例如,为什么您的Java如此密集地调用本机代码(反之亦然)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM