Question about LDC and --gc-sections

H. S. Teoh hsteoh at quickfur.ath.cx
Fri Oct 26 16:24:50 UTC 2018


On Friday, 26 October 2018 at 06:02:51 UTC, Joakim wrote:
[...]
> Btw, are you writing a mostly native app that calls some D code 
> or a Java app that calls some native code? I ask because I ran 
> into an issue before depending on how it's set up, though you 
> won't hit this if you're using D in betterC mode.

My main code is in D, but consists of a bunch of functions 
repeatedly called from the Java wrapper as native functions. Main 
reason is that for GUI interactions it makes more sense to 
leverage the Java APIs provided by Android, rather than to go 
through the pain of marshalling and calling Java functions via 
JNIEnv. (There are a couple of places where this is necessary, 
e.g., when D code needs to trigger a GUI action, but I'm trying 
to keep this to a minimum.)


> The difference is that there are two ways of calling native 
> code on Android:
>
> 1. You can have the Android Java runtime directly call native 
> code on _startup_ if you provide some standard native functions 
> that it expects:
>
> https://developer.android.com/ndk/reference/group/native-activity#group___native_activity_1ga02791d0d490839055169f39fdc905c5e

That's something to look into, I suppose.


> 2. You have your Java app call some native functions using JNI.
>
> Both have been tried with D, but the latter may present some 
> difficulty for initializing the D runtime and GC. When I tried 
> the latter with a sample app, it seemed to be loading the D 
> library _every time_ the D functions were called, so I had to 
> add a call to rt_init every time the function was called:
>
> https://github.com/joakim-noah/android/blob/master/samples/bitmap-plasma/jni/plasma.d#L357
>
> I initially had that call inside the initialization check just 
> below, and it wouldn't work. I never investigated further 
> though, as I have no interest in using D that way, I could be 
> completely off on my guess as to why it didn't work.

Currently, I call rt_init() from a native function called from 
Java whenever onSurfaceCreated is called (I'm using GLES2).  I 
don't know if Android reloads the library every time, but I see 
why it might, seeing that it can shut down activities anytime 
without (much) notice.  So far, I haven't encountered any 
problems.

Other native functions do save static state in TLS, and so far I 
haven't encountered any problems.  But maybe I just haven't 
triggered the problematic cases yet.


> For the way I use D and test it, the rt_init is called once on 
> startup, as noted on the wiki, so everything works:
>
> https://wiki.dlang.org/Build_D_for_Android#Changes_for_Android
>
> Of course, you can always call Java functions through JNI if 
> you go this route, as the Teapot sample app demonstrates, just 
> something to consider in how you call D code.

Currently I'm expecting to just write the Activity code in Java 
and have it easily interact with the Android GUI APIs, and call 
the main logic in D via JNI.  I *could* use the NDK APIs if I 
really wanted to, I suppose, but I don't really have a strong 
reason to do that currently.  (The main reason I looked into 
using D at all in this project was because I got frustrated 
trying to write complex non-GUI code in Java.  So far, I've 
migrated most of the original Java code to D, leaving the Java 
code merely as thin wrappers that just forward the main logic to 
D via JNI.  It has worked well thus far, and I'll probably just 
leave it this way, unless I run into something that would be far 
better off written in D.  I'm not looking forward to interfacing 
with Android GUI classes via JNI, though.  JNI is a royal pain to 
use, esp. when going from D to Java.)

I do have an empty main() in the .so, though, per your 
recommendations on that wiki page.  Does that make a difference?


--T


More information about the Digitalmars-d mailing list