Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 16, 2013 Interfacing via Java Native Interface | ||||
---|---|---|---|---|
| ||||
Hello there! I've decided to learn a bit of D, as I am currently Android Developer (mostly C++ <- JNI -> Java), I'm trying to create a D shared library which exports function (with extern (C)) for invocation from Java. My .d file contains only a single function returning an int, .java calls this function several times. This approach only works if d-function is trivial, e.g. it's not using any D functionality (I believe that it is related to GC and memory allocation). For example, if my d-function just returns some constant integer, java side receives it. core.stdc.stdio also works and allows console output, but it's not the case with std.stdio.writeln and similar functions. If I use any d-specific functions my program crashes while calling native code with some weird message like following: "Invalid memory access of location 0x0 rip=addr". It seems like D is not initialized at all, maybe there is some internal function like dinit() which I can call in order to activate everything? Thanks. |
October 16, 2013 Re: Interfacing via Java Native Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew | On Wednesday, 16 October 2013 at 10:11:32 UTC, Andrew wrote:
> Hello there!
> I've decided to learn a bit of D, as I am currently Android Developer (mostly C++ <- JNI -> Java), I'm trying to create a D shared library which exports function (with extern (C)) for invocation from Java.
> My .d file contains only a single function returning an int, .java calls this function several times.
> This approach only works if d-function is trivial, e.g. it's not using any D functionality (I believe that it is related to GC and memory allocation).
> For example, if my d-function just returns some constant integer, java side receives it. core.stdc.stdio also works and allows console output, but it's not the case with std.stdio.writeln and similar functions.
> If I use any d-specific functions my program crashes while calling native code with some weird message like following:
> "Invalid memory access of location 0x0 rip=addr".
>
> It seems like D is not initialized at all, maybe there is some internal function like dinit() which I can call in order to activate everything?
>
> Thanks.
JNI requires (to some degree) compiler support. This could be done in gdc as backend support is there because of g++ JNI interface to gcj. But it would be some magic module or change to the language to add the Java types to the language.
Regards
Iain.
|
October 16, 2013 Re: Interfacing via Java Native Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | On Wednesday, 16 October 2013 at 10:15:17 UTC, Iain Buclaw wrote:
> On Wednesday, 16 October 2013 at 10:11:32 UTC, Andrew wrote:
>> Hello there!
>> I've decided to learn a bit of D, as I am currently Android Developer (mostly C++ <- JNI -> Java), I'm trying to create a D shared library which exports function (with extern (C)) for invocation from Java.
>> My .d file contains only a single function returning an int, .java calls this function several times.
>> This approach only works if d-function is trivial, e.g. it's not using any D functionality (I believe that it is related to GC and memory allocation).
>> For example, if my d-function just returns some constant integer, java side receives it. core.stdc.stdio also works and allows console output, but it's not the case with std.stdio.writeln and similar functions.
>> If I use any d-specific functions my program crashes while calling native code with some weird message like following:
>> "Invalid memory access of location 0x0 rip=addr".
>>
>> It seems like D is not initialized at all, maybe there is some internal function like dinit() which I can call in order to activate everything?
>>
>> Thanks.
>
>
> JNI requires (to some degree) compiler support. This could be done in gdc as backend support is there because of g++ JNI interface to gcj. But it would be some magic module or change to the language to add the Java types to the language.
>
> Regards
> Iain.
As far as I know, calling C from Java only requires is <jni.h> header. It can mimicked with mere D aliases. I'm currently not talking about calling Java from D, although it could be possible by writing C-wrapper library.
I just can't understand why D code compiled as a shared library does not work when called from Java. Why does it (does it?) work when called from C?
|
October 16, 2013 Re: Interfacing via Java Native Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew | On Wednesday, 16 October 2013 at 10:11:32 UTC, Andrew wrote:
> Hello there!
> I've decided to learn a bit of D, as I am currently Android Developer (mostly C++ <- JNI -> Java), I'm trying to create a D shared library which exports function (with extern (C)) for invocation from Java.
> My .d file contains only a single function returning an int, .java calls this function several times.
> This approach only works if d-function is trivial, e.g. it's not using any D functionality (I believe that it is related to GC and memory allocation).
> For example, if my d-function just returns some constant integer, java side receives it. core.stdc.stdio also works and allows console output, but it's not the case with std.stdio.writeln and similar functions.
> If I use any d-specific functions my program crashes while calling native code with some weird message like following:
> "Invalid memory access of location 0x0 rip=addr".
>
> It seems like D is not initialized at all, maybe there is some internal function like dinit() which I can call in order to activate everything?
>
> Thanks.
Try using Runtime.init() from core.runtime
|
October 16, 2013 Re: Interfacing via Java Native Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Wednesday, 16 October 2013 at 10:41:35 UTC, John Colvin wrote:
> On Wednesday, 16 October 2013 at 10:11:32 UTC, Andrew wrote:
>> Hello there!
>> I've decided to learn a bit of D, as I am currently Android Developer (mostly C++ <- JNI -> Java), I'm trying to create a D shared library which exports function (with extern (C)) for invocation from Java.
>> My .d file contains only a single function returning an int, .java calls this function several times.
>> This approach only works if d-function is trivial, e.g. it's not using any D functionality (I believe that it is related to GC and memory allocation).
>> For example, if my d-function just returns some constant integer, java side receives it. core.stdc.stdio also works and allows console output, but it's not the case with std.stdio.writeln and similar functions.
>> If I use any d-specific functions my program crashes while calling native code with some weird message like following:
>> "Invalid memory access of location 0x0 rip=addr".
>>
>> It seems like D is not initialized at all, maybe there is some internal function like dinit() which I can call in order to activate everything?
>>
>> Thanks.
>
> Try using Runtime.init() from core.runtime
Wow, thanks! Now everything works, proving that my guess on uninitialized runtime was correct.
It's actually Runtime.initialize() according to documentation, by the way.
|
October 16, 2013 Re: Interfacing via Java Native Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | On Wednesday, 16 October 2013 at 10:15:17 UTC, Iain Buclaw wrote: > On Wednesday, 16 October 2013 at 10:11:32 UTC, Andrew wrote: >> Hello there! >> I've decided to learn a bit of D, as I am currently Android Developer (mostly C++ <- JNI -> Java), I'm trying to create a D shared library which exports function (with extern (C)) for invocation from Java. >> My .d file contains only a single function returning an int, .java calls this function several times. >> This approach only works if d-function is trivial, e.g. it's not using any D functionality (I believe that it is related to GC and memory allocation). >> For example, if my d-function just returns some constant integer, java side receives it. core.stdc.stdio also works and allows console output, but it's not the case with std.stdio.writeln and similar functions. >> If I use any d-specific functions my program crashes while calling native code with some weird message like following: >> "Invalid memory access of location 0x0 rip=addr". >> >> It seems like D is not initialized at all, maybe there is some internal function like dinit() which I can call in order to activate everything? >> >> Thanks. > > > JNI requires (to some degree) compiler support. This could be done in gdc as backend support is there because of g++ JNI interface to gcj. But it would be some magic module or change to the language to add the Java types to the language. > > Regards > Iain. I was talking about calling D from Java in following fashion: https://gist.github.com/DieHertz/7005898 Java calls dinit in static initializer after loading shader library and then proceeds with calling dget. |
October 16, 2013 Re: Interfacing via Java Native Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew | On Wednesday, 16 October 2013 at 10:53:28 UTC, Andrew wrote: > On Wednesday, 16 October 2013 at 10:41:35 UTC, John Colvin wrote: >> On Wednesday, 16 October 2013 at 10:11:32 UTC, Andrew wrote: >>> Hello there! >>> I've decided to learn a bit of D, as I am currently Android Developer (mostly C++ <- JNI -> Java), I'm trying to create a D shared library which exports function (with extern (C)) for invocation from Java. >>> My .d file contains only a single function returning an int, .java calls this function several times. >>> This approach only works if d-function is trivial, e.g. it's not using any D functionality (I believe that it is related to GC and memory allocation). >>> For example, if my d-function just returns some constant integer, java side receives it. core.stdc.stdio also works and allows console output, but it's not the case with std.stdio.writeln and similar functions. >>> If I use any d-specific functions my program crashes while calling native code with some weird message like following: >>> "Invalid memory access of location 0x0 rip=addr". >>> >>> It seems like D is not initialized at all, maybe there is some internal function like dinit() which I can call in order to activate everything? >>> >>> Thanks. >> >> Try using Runtime.init() from core.runtime > > Wow, thanks! Now everything works, proving that my guess on uninitialized runtime was correct. No problem. > It's actually Runtime.initialize() according to documentation, by the way. Ah yeah, sorry I misremembered. |
October 16, 2013 Re: Interfacing via Java Native Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew | On 2013-10-16 12:53, Andrew wrote: > Wow, thanks! Now everything works, proving that my guess on > uninitialized runtime was correct. > It's actually Runtime.initialize() according to documentation, by the way. If you're calling it from C it might be more correct to call this function: https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L161 It's what Runtime.initialize calls. -- /Jacob Carlborg |
October 16, 2013 Re: Interfacing via Java Native Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Wednesday, 16 October 2013 at 11:01:33 UTC, Jacob Carlborg wrote:
> On 2013-10-16 12:53, Andrew wrote:
>
>> Wow, thanks! Now everything works, proving that my guess on
>> uninitialized runtime was correct.
>> It's actually Runtime.initialize() according to documentation, by the way.
>
> If you're calling it from C it might be more correct to call this function:
>
> https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L161
>
> It's what Runtime.initialize calls.
Agreed. You can't call Runtime.initialize from outside D due to name mangling (and maybe ABI, depending on your system).
However, other than that it really makes no difference which you call, Runtime.initialize is just a no-op wrapper around rt_init.
|
October 16, 2013 Re: Interfacing via Java Native Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Wednesday, 16 October 2013 at 11:01:33 UTC, Jacob Carlborg wrote:
> On 2013-10-16 12:53, Andrew wrote:
>
>> Wow, thanks! Now everything works, proving that my guess on
>> uninitialized runtime was correct.
>> It's actually Runtime.initialize() according to documentation, by the way.
>
> If you're calling it from C it might be more correct to call this function:
>
> https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L161
>
> It's what Runtime.initialize calls.
Thanks for advice, I'll use it when I'm interfacing C with D :-)
For now I can't use it directly because a native function called from java requires a name with "Java_" prefix, so I'd have to write a wrapper with such prefix anyway.
|
Copyright © 1999-2021 by the D Language Foundation