简体   繁体   中英

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. Right now in my C code I have got this:

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] . Later in code tmp1 is being used as an input argument:

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

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. 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.

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?

Not answering the question but trying to help with the problem. JNA has 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. You will only have to make sure that you've got the correct encoding.

Instead of function.invoke(myString); which gives you a multibyte string on the native side, just use 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.

But these approaches won't work you are using zero-terminated char* values. Java's standard APIs don't support zero-termination. (A Java array has a well-defined length.)

My advice would be to not directly translate your code from C / C++ to Java. Instead, write it from scratch as idiomatic Java code. (And if you really need the efficiency of C or C++ code, use those languages!)

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.

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.
  2. Pass the byte[] or String or whatever to Java via JNA.
  3. Have the Java side cache it so that the JNA call doesn't need to be repeated.

But it it is worth noting Knuth's advice about premature optimization. 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; eg why your Java is calling native code so intensively (or vice versa).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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