digitalmars.D.learn - how to invoke D from java through JNI ? [ Linux ]
- outersky <outersky gmail.com> Nov 07 2007
- Frank Benoit <keinfarbton googlemail.com> Nov 08 2007
Content-Type: text/plain; charset=GB2312
Content-Transfer-Encoding: 7bit
hi, all
I'm using ubuntu gutsy and jdk6 , and can run D and java programs.
Now I can call c functions from java through JNI.
I need convert .o file to .so for c files. But when I did so with D
files, It did not work, and output the error message as :
-------------8<---Error message----------------
java.lang.UnsatisfiedLinkError:
/mnt/work/dev/d/java/jni3/libfunc.so:
/mnt/work/dev/d/java/jni3/libfunc.so: undefined symbol: _Dmodule_ref
java: symbol lookup error: /mnt/work/dev/d/java/jni3/libhello.so:
undefined symbol: hello
-------------8<---Error message----------------
I don't know how to write JNI application with D directly, so I call D
from C , and call C from java :)
Following is my source code, and the attachment jni.zip has the same
content , and is for your convinence to test.
-------------8<------Hello.java-------------8<------------------
public class Hello{
static{
try{
System.loadLibrary("hello");
System.loadLibrary("func");
}catch(UnsatisfiedLinkError e){
System.err.println( "Cannot load library:\n " +e.toString() );
}
}
public Hello(){
}
public native void SayHello(String strName);
}
-------------8<------Hello.java-------------8<------------------
and java generate Hello.h as
-------------8<------Hello.h-------------8<------------------
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Hello */
#ifndef _Included_Hello
#define _Included_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Hello
* Method: SayHello
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_Hello_SayHello
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
-------------8<------Hello.h-------------8<------------------
-------------8<------Hello.c-------------8<------------------
#include "Hello.h"
#include <string.h>
// want to call hello written in D
extern void hello(const char* name);
JNIEXPORT void JNICALL Java_Hello_SayHello
(JNIEnv * env, jobject arg, jstring string){
const char *str = (*env)->GetStringUTFChars(env, string, 0);
//printf("Hello:%s\n",str);
hello(str);
}
-------------8<------Hello.c-------------8<------------------
-------------8<----- func.d-------------8<------------------
extern(C){
void hello(const char* name){
printf("Hello from D: %s",name);
}
}
-------------8<------func.d-------------8<------------------
Here is my build file:
-------------8<------build-------------8<------------------
#!/bin/sh
echo "Compiling Hello.java ..."
javac Hello.java
echo "Generate Hello.h ..."
javah Hello
echo "Compile Hello.c , Generate Hello.o ..."
gcc -I/mnt/soft/jdk/include -I/mnt/soft/jdk/include/linux -fPIC -c Hello.c
echo "Compile func.d ..."
dmd -g -c func.d
echo "Generate shared library libhello.so.1.0"
gcc -shared -W1,-soname,libhello.so.1 -o libhello.so.1.0 Hello.o
echo "Generate shared library libfunc.so.1.0"
gcc -shared -W1,-soname,libfunc.so.1 -o libfunc.so.1.0 func.o
echo "copy libhello.so.1.0 to libhello.so"
cp libhello.so.1.0 libhello.so
echo "copy libfunc.so.1.0 to libfunc.so"
cp libfunc.so.1.0 libfunc.so
echo "Set LD_LIBRARY_PATH ..."
export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
echo "Now: LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
echo "Compile Main.java ..."
javac Main.java
echo "Run java Main ..."
java Main
-------------8<------build-------------8<------------------
Note : My jdk is installed in /mnt/soft/jdk , you should correct this
if you want to run the build file.
Thanks!
outerky
Nov 07 2007
Hi I think you will not succeed with JNI. The ultimative problem is, both Java and D have Garbage Collectors. They both need to have control over which threads are running or not. So this is a really hard problem. Better solution is to make inter process communication. I am working on a DBus binding for D. And actually i am already using it in an application. In the moment this enable you to call D from Java. The other direction will follow in some time. you can download the source with mercurial version control: hg clone http://hg.assembla.com/dbus-d Frank
Nov 08 2007








Frank Benoit <keinfarbton googlemail.com>