String literals for JNI call (C API)

island

(Benoît Bousquet) #1

Running across a weird issue in my Silver/Island Windows DLL. This is shared code that is running fine in a Silver/Toffee macOS shared library.

I have helper classes to wrap some common JNI types. The constructor instantiates the actual Java object using the JNI C API:

let method: jmethodID = (*(*env)).GetMethodID(env, objClass, "<init>", "(JJ)V")

This line causes a crash in the JVM:

Stack: [0x18550000,0x185a0000],  sp=0x1859e308,  free space=312k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [jvm.dll+0xe7c00]
V  [jvm.dll+0xe7d9b]
C  [mydll.dll+0x718cd]  GC_strndup+0x1063d
C  [mydll.dll+0x65900]  GC_strndup+0x4670
C  [mydll.dll+0x722d1]  Java_myfunction(...)+0x131
(...)

It’s as if Island doesn’t handle the string literals properly. The imported rtl.java function is as follows:

public struct rtl.java.JNINativeInterface_ { 
        public var GetMethodID: (UnsafePointer<JNIEnv!>, jclass!, UnsafePointer<AnsiChar>, UnsafePointer<AnsiChar>) -> jmethodID!
}

I attempted to pass them as “”.ToString().ToAnsiChars(true) and the JVM crashed brutally with an EXCEPTION_STACK_OVERFLOW.

Ideas?


(marc hoffman) #2

do you get more of the actual stack trace than sown here? what’s Java_myfunction? What’s the exact sig for GetMethodID (and why it is called on env bout also gets env as first parameter? whats objClass?

Very possible; by default they are Island Strings, not C Strings, I’m guessing GetMethod expects *char? Maybe we dont do the type inference right. wha happens if you split this:

let a: UnsafePointer<AnsiChar> = "<init>"
bet b: : UnsafePointer<AnsiChar> = "(JJ)V"
let method: jmethodID = (*(*env)).GetMethodID(env, objClass, a, b)

?


(Benoît Bousquet) #3

This doesn’t compile:


(RemObjects) #4

Thanks, logged as bugs://79892


(Carlo Kok) #5

this works:

typealias pchar = UnsafePointer<RemObjects.Elements.System.AnsiChar>

writeLn("The magic happens here.")
let a: pchar = "<init>"
let b: pchar = "(JJ)V"

Looks like Swift defines it’s own (wrong) ansichar. I’ll look into fixing it.


(RemObjects) #6

bugs://79892 got closed with status fixed.


(Benoît Bousquet) #7

This is still a little hazy for me. My new test app is still crashing on that line and the problem with the local variables not showing or being ‘optimized out’ is preventing me from understanding what is what, type-wise.

EDIT:
"<init>".ToString().ToAnsiChars() works fine now. I guess I’ll have to #ifdef anything String related there as well (code is shared between Toffee and Island).