Wrapping C/C++ inside Java

前端 未结 8 1490
Happy的楠姐
Happy的楠姐 2021-02-07 09:24

I develop applications/programs in C/C++. I am more versed in these two languages and love being a C++ developer. I am wondering how to create a Java program that contains all m

相关标签:
8条回答
  • 2021-02-07 09:30

    You can write C++ code through JNI but there isn't a direct mapping from C++ classes to Java classes. I've used JNI to fix problems found in the android SDK (specifically, an incredibly slow FloatBuffer.put implementation) and I may end up using it for some performance critical areas. My advice would be to be use it sparingly and in a duck in, do the performance critical stuff and leave, without doing any memory allocation if you can help it. Also, don't forget to measure your code to see if it really is faster.

    Out of interest, what platform are you developing for? The only platform where it would make sense to wrap a lot of C++ code in a light java layer would be Android - on other platforms, just compile in C++ and have done with it.

    0 讨论(0)
  • 2021-02-07 09:31

    There are plenty of tutorials for doing exactly what you want to do. For example, check out: http://www.javamex.com/tutorials/jni/getting_started.shtml

    There are also plenty of caveats of using JNI. I've recently started working with it (just for fun, really), and it tends to be a lot less fun than I had first anticipated.

    First of all, you have to deal with cryptic code such as:

    #include "test_Test.h"
    
    JNIEXPORT jint JNICALL Java_test_Test_getDoubled(JNIEnv *env, jclass clz, jint n) {
        return n * 2;
    }
    

    Second of all, it tends to downplay one of the primary reasons why you use Java in the first place: WORA (Write Once, Run Anywhere). As duffymo mentioned, there can also be issues with the garbage collector, but I think that in recent years, the JVM has gotten pretty smart about JNI integration.

    With that said, to port all of your C++ code to JNI, you'd need to refactor your interfaces (and maybe even do some internal gymnastics). It's not impossible, but it's really not recommended. The ideal solution is just re-writing your code in Java.

    With that said, you could also "convert" your code from C/C++ into Java programatically, and there are multitudes of such utilities. But, of course, machines are dumber than people and they are also bound to make mistakes, depending how complex your class is.

    0 讨论(0)
  • 2021-02-07 09:37

    You can't "just wrap it", you have to write some C/C++ glue.

    For starters, SWIG can do most of the works for you.

    0 讨论(0)
  • 2021-02-07 09:38

    Instead of JNI, or JNI with some assist from an automatic wrapper generator like SWIG, or even JNA, you might consider separating the C/C++ and Java into separate processes and using some form of IPC and/or Java's Process abstraction to call to a program written in C/C++. This approach abandons "wrapping," so in some sense it isn't an answer to this question, but please read on before down-voting. I believe that this is a reasonable answer to the broader issue in some cases.

    The reason for such an approach is that when you call C/C++ directly from Java, the JVM is put at risk of any error in the native code. The risk depends somewhat on how much of the native code is yours and how much you link to third party code (and how much access you have to the source code of such third party code).

    I've run into a situation where I had to call a C/C++ library from Java and the C/C++ library had bugs that caused the JVM to crash. I didn't have the third party source code, so I couldn't fix the bug(s) in the native code. The eventual solution was to call a separate C/C++ program, linked to the third party library. The Java application then made calls to many ephemeral native processes whenever it needed to call the C/C++ stuff.

    If the native code has a problem, you might be able to recover/retry in Java. If the native code is wrapped and called from the JVM process, it could take down the entire JVM.

    This approach has performance/resource consumption implications and may not be a good fit for your application, but it is worth considering in certain situations.

    Having a separate application that exercises the functionality of the C/C++ code is potentially useful as a stand-alone utility and for testing. And having some clean command-line or IPC interface could ease future integrations with other languages.

    As another alternative, you could get into native signal handling to mitigate the risks to the integrity of the JVM process if you like and stick with a wrapping solution.

    0 讨论(0)
  • 2021-02-07 09:41

    BridJ was designed on purpose for that (and it's supported by JNAerator, which will parse your C/C++ headers and spit out the Java bindings for you).

    It is a recent alternative to JNA, with support for C++.

    0 讨论(0)
  • 2021-02-07 09:45

    If you want to call C++ from Java, you'll need to use JNI - Java Native Interface.

    Be warned that you lose some of the benefits of the garbage collector, since it can't deal with your C++ objects, and your code won't be portable anymore.

    Maybe you'd be better served by learning to write 100% Java and leaving C++ behind, but that's just a suggestion.

    0 讨论(0)
提交回复
热议问题