Nim programming language finally hit 1.0

H. S. Teoh hsteoh at quickfur.ath.cx
Thu Oct 3 19:33:37 UTC 2019


On Thu, Oct 03, 2019 at 06:27:46PM +0000, Adam D. Ruppe via Digitalmars-d wrote:
[...]
> That's part of what we still need to figure out. What I'm aiming for
> in the first version is you compile the D code with ldc then work the
> generated shared object back into your workflow, which won't be
> modified; you just make the blob then drop it in as if it was a
> closed-source library.

BTW, I do have an android project that involves a combination of D code
and Java code.  It's cross-compiled from PC to the Android platform.
Although it's not your typical Android project (I eschewed Android
Studio in favor of my own SCons-based build script, mainly because I
need to compile helper D programs that in turn generate D code for
certain repetitive modules, but also because I can't be bothered with a
resource-intensive IDE when a text editor works just as well), I'll be
happy to provide details on the steps that worked for me.

Basically, an APK can include Java bytecode, resources (XML, media,
etc.), and, most importantly, a lib/ subdirectory for precompiled .so
files. I took the route of using Java to interface with Android OS:
there's a C API available that I *could* use if I wanted to, but I
didn't want to have to reinvent the Java GUI bindings already available
to Java code, so I just have the Java code declare native methods that
are implemented by the .so (containing D code) via JNI.

Compilation essentially amounts to running ldc on the D code to produce
a .so that the build system inserts into the correct location in the
APK, and the usual Java compilation and assembly into classes.dex, as
required by Android, along with packing up the standard APK resources.
Then run the tools in the Android SDK/NDK to process the APK, sign it,
and what-not, then it's ready to be uploaded to your device for
installation.


> Second pass is possibly a plugin with android studio, or at least the
> build system. I'm actually totally new to mobile dev (I personally
> don't even use smartphone apps!) so lots of learning as I go. I'm
> pretty thankful for the work the ldc people have already done on this,
> as well as the prior art Joakim did before he left.

Yes, my project got off the ground only because of the work Joakim did
to make transcompilation to Android possible with LDC. There are some
pretty specific details that you have to get right, otherwise your APK
won't work.


[...]
> > Are there any plans for auto generated bridges, e.g. JNI calling
> > rt_init() or something?
> 
> I do want to put the bindings to the NDK into druntime as well in
> core.sys.android. The D foundation is officially backing this work
> which makes that more realistic.

That would be VERY nice. Currently, in my code, I have to take extra
care to call rt_init() and rt_cleanup() at the right junctures -- and
this stuff is pretty delicate; get it wrong and it will crash at
runtime, usually with no useful indication of what went wrong (you just
get the "sorry, application crashed" message).

I also have the beginnings of a JNI boilerplate auto-generator in my
project, basically a template function that lets D code invoke a named
Java method on a JNI-wrapped Java object. If you like, I can send you a
copy for reference.  Though keep in mind it's *very* crude, and I wrote
just enough for my own needs, so it will need more work to be suitable
for general consumption.  But at the very least, it lets me call Java
methods like this:

	// Equivalent to Java:
	//	int ret = classObj.myMethod(123, "abc", 1.0);
	int ret = callJavaMethod!(int, "myMethod")(jniHandle, classObj,
		123, "abc", 1.0);

which, if you were to write it manually in terms of JNI calls, would be
like a 25-50 line function in itself. (JNI is *very* boilerplate-y.)

In theory, this could be expanded upon by wrapping Java class objects
received over JNI in a JavaObject wrapper that contains an implicit
JNI handle, so that you could actually write the above as:

	int ret = classObjWrapper.myMethod(123, "abc", 1.0);

This can probably be done with good ole opDispatch.  But so far, I
haven't found the need for it yet, since my focus is mainly on the D
code, and calling Java methods from D isn't really a priority except for
some unavoidable calls to interact with the Android GUI API.

One gotcha to watch out for, if you ever decide to go that route, is
that the JNI handle handed to the D code by JNI is NOT guaranteed to be
valid across different JNI calls; so if you do wrap your class objects
like above, you have to be careful that you don't reuse stale JNI
handles you obtained from previous JNI calls. Otherwise you may get
random unexplained crashes at runtime. This is one of the reasons I
haven't bothered to write such a wrapper just yet -- it's too much
trouble to write code to handle the JNI handle correctly at the moment.

Another challenge is that you can't deduce the Java return type of a
method at D compile-time -- this is why callJavaMethod above requires a
compile-time argument to specify the return type -- so you may have to
resort to some heavy hackery if you want to be able to just assign the
return value to a target variable without needing the user to explicitly
specify the type.  One approach that comes to mind is a tool that parses
Java source code and emits equivalent D declarations that are then
introspected by the Java class wrapper to obtain the correct method
signatures. But again, a lot of work for something that I don't
presently feel an urgent need for right now.

(And, to dream on, in the future we could potentially have built-in Java
support in D, in a similar style that we interface with C/C++ today:
declare Java classes/methods using D equivalents, and have the compiler
or a library auto-generate the JNI code for it.  Or potentially just
ditch JNI and use JNA instead, which is far less boilerplate-y. But as
far as Android is concerned, JNA may not be available yet, so for the
near future JNI seems to the way to go.)


T

-- 
WINDOWS = Will Install Needless Data On Whole System -- CompuMan


More information about the Digitalmars-d mailing list