[cfe-dev] clang via JNI + libclang-c

Anton Smirnov dev at antonsmirnov.name
Fri Oct 11 02:02:44 PDT 2013


 Well, that sounds like it will not work because of JNI?

In few words, i'm trying to invoke indexing, parsing and tokenizing from
java using libclang.

// create index
    native public static Index createIndex(boolean
excludeDeclarationsFromPCH);

    // parse translation unit from file
    native public static TranslationUnit parseTranslationUnit(Index index,
String filename, String[] commandLineArgs, UnsavedFile[] unsavedFiles);

    // tokenize
    native public static Token[] tokenize(TranslationUnit translationUnit,
String filename, int filesize);

    // dispose translation unit
    native public static void dispose(TranslationUnit translationUnit);

    // dispose index
    native public static void dispose(Index index);

for this methods there is native code with according methods and java
nandles invocation from java code to native:

/*
 * Class:     name_antonsmirnov_clang_clang_wrapper
 * Method:    createIndex
 * Signature: (Z)Lname/antonsmirnov/clang/dto/Index;
 */
JNIEXPORT jobject JNICALL
Java_name_antonsmirnov_clang_clang_1wrapper_createIndex
  (JNIEnv *env, jobject obj, jboolean excludeDeclarationsFromPCH)
  {
...
}

/*
 * Class:     name_antonsmirnov_clang_clang_wrapper
 * Method:    parseTranslationUnit
 * Signature:
(Lname/antonsmirnov/clang/dto/Index;Ljava/lang/String;[Lname/antonsmirnov/clang/dto/UnsavedFile;[Ljava/lang/String;)Lname/antonsmirnov/clang/dto/TranslationUnit;
 */
JNIEXPORT jobject
Java_name_antonsmirnov_clang_clang_1wrapper_parseTranslationUnit
  (JNIEnv *env, jobject obj, jobject jindex, jstring jfilename,
jobjectArray commandLineArgs, jobjectArray unsavedFiles)
  {

...
}

so i map classes from java to native code and vice versa.
In native methods i invoke libclang-c methods.

The problem is that CXIndex and CXTranslationUnit should be passed in the
next methods so i have to keep them in memory in native code,
pass pointer to java as long and then return back with casting long as
pointer.
I'm absolutely sure that pointers are packed/unpacked (long <--> pointer)
correctly.

The problem is that if i do in the same invocation from java (f.e. in
single Java_name_antonsmirnov_clang_clang_1wrapper_tokenize() function) -
it works good.
For example if i just remember parameters and then create index, parse,
tokenize (clang-c invocations) within tokenize() method it's okay.

If i do everything in separate native methods (clang-c invocation in
separate native calls from java) (as it's designed to do) pointers are
corrupted.
So unpacked CXIndex in parse() invocation is corrupted even if it was
packed/unpacked correctly and the pointer is the same.

Any thoughts? Is is libclang problem, jni problem or i'm doing smth wrong?



2013/10/11 Renato Golin <renato.golin at linaro.org>

> On 11 October 2013 08:02, Anton Smirnov <dev at antonsmirnov.name> wrote:
>
>> Are there any obvious limitations or anybody with such experience?
>>
>
> Yes, JNI.
>
> JNI is a poor implementation of C code, trying to deal with the poor
> definitions of Java code, at the same time as trying to be 100%
> cross-platform. It fails on all three levels.
>
> Stack corruption in JNI is surprisingly common, especially on Windows (but
> also on Linux), and a few tricks must be used if you pass more than just a
> char pointer. On the top of my head I remember I had to define a large
> array on the stack, so that the stack pointer wouldn't segfault.
>
> JNI is also surprisingly poor in propagating errors from the C layer to
> the Java layer (if at all), so catching errors and debugging the interface
> is downright nightmare.
>
> You would hope that, after all these years, someone would come up with a
> fix, or a better infrastructure for inter-operating C code with Java...
>
> This is a long shot, but have you tried using the VMKit and sharing C and
> Java code via LLVM's Execution Engine? I heard of a project that managed to
> do that with Python+C, including exception handling, so it should be
> possible to do that with Java.
>
> cheers,
> --renato
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131011/f8e8ca10/attachment.html>


More information about the cfe-dev mailing list