August 03, 2016 Re: C binding with D function | ||||
---|---|---|---|---|
| ||||
Posted in reply to llaine | On Wednesday, 3 August 2016 at 15:24:56 UTC, llaine wrote:
> On Wednesday, 3 August 2016 at 15:14:24 UTC, Kagamin wrote:
After digging a bit more, I get a different error.
import std.stdio;
import core.runtime;
extern(C)
{
void initialize()
{
Runtime.initialize();
}
void foo(string str)
{
writeln(str);
}
void terminate()
{
Runtime.terminate();
}
}
on my code ofc I call the three methods and I get
uncaught exception
dwarfeh(224) fatal error
Abandon (core dumped)
|
August 03, 2016 Re: C binding with D function | ||||
---|---|---|---|---|
| ||||
Posted in reply to llaine | On Wednesday, 3 August 2016 at 15:24:56 UTC, llaine wrote:
> On Wednesday, 3 August 2016 at 15:14:24 UTC, Kagamin wrote:
>> On Wednesday, 3 August 2016 at 15:08:51 UTC, llaine wrote:
>>> So basically I have to create wrapper.c ?
>>
>> Yes, but you should write it in D. Runtime initialization is at https://dlang.org/phobos/core_runtime.html#.Runtime
>
> Okay I tried to do something like this
>
>
> import std.stdio;
> import core.runtime;
>
> extern(C)
> {
>
> void foo(string str)
> {
> writeln(str);
> }
>
> }
>
> void main(){
> Runtime.initialize();
> Runtime.terminate();
> }
>
> Am I doing it wrong ?
> Still getting a Segmentation fault
I have no way to test this, but translating the example to D, I get this:
import core.runtime;
import std.stdio;
extern(C) {
example_init() {
Runtime.initialize();
}
example_exit() {
Runtime.terminate();
}
void foo(int x) {
writeln(2*x);
}
}
// No main
// compile as libffi-example.so
Then in Ruby:
module Example
extend DL::Importable
dlload "./libffi-example.so"
extern "void example_init()"
extern "void example_exit()"
extern "void foo(int)"
end
Example.example_init
Example.foo(3)
Example.example_exit
|
August 03, 2016 Re: C binding with D function | ||||
---|---|---|---|---|
| ||||
Posted in reply to bachmeier | On Wednesday, 3 August 2016 at 15:47:48 UTC, bachmeier wrote:
> On Wednesday, 3 August 2016 at 15:24:56 UTC, llaine wrote:
>> On Wednesday, 3 August 2016 at 15:14:24 UTC, Kagamin wrote:
>>> On Wednesday, 3 August 2016 at 15:08:51 UTC, llaine wrote:
>>>> So basically I have to create wrapper.c ?
>>>
>>> Yes, but you should write it in D. Runtime initialization is at https://dlang.org/phobos/core_runtime.html#.Runtime
>>
>
> // No main
> // compile as libffi-example.so
>
> Then in Ruby:
>
> module Example
> extend DL::Importable
> dlload "./libffi-example.so"
> extern "void example_init()"
> extern "void example_exit()"
> extern "void foo(int)"
> end
>
> Example.example_init
> Example.foo(3)
> Example.example_exit
Okay on stack overflow, they are not using ffi but dl.
I tried changing ffi to dl, it's the same don't work unfortunatly.
|
August 03, 2016 Re: C binding with D function | ||||
---|---|---|---|---|
| ||||
Posted in reply to llaine | On Wednesday, 3 August 2016 at 15:56:34 UTC, llaine wrote:
> Okay on stack overflow, they are not using ffi but dl.
> I tried changing ffi to dl, it's the same don't work unfortunatly.
That's about as far as I can go without having it set up on my machine. The procedure should be the same as I spelled out though. You need to create an extern(C) function that calls Runtime.initialize(). Then you call that function from Ruby the same as any other function you call with FFI. I'm familiar with the R FFI and the only difference is that some parts of that are automated.
|
August 03, 2016 Re: C binding with D function | ||||
---|---|---|---|---|
| ||||
Posted in reply to llaine | On Wednesday, 3 August 2016 at 15:56:34 UTC, llaine wrote: > > Okay on stack overflow, they are not using ffi but dl. > I tried changing ffi to dl, it's the same don't work unfortunatly. This FFI example calls an init function from a library: https://github.com/ffi/ffi/blob/ce0e712bcb8876620e10c892d0b9005c84d92b53/samples/inotify.rb |
August 04, 2016 Re: C binding with D function | ||||
---|---|---|---|---|
| ||||
Posted in reply to llaine | On Wednesday, 3 August 2016 at 15:41:55 UTC, llaine wrote:
> void foo(string str)
> {
> writeln(str);
> }
>
shouldn't foo be:
void foo(char* str) {
import std.string;
writeln(str.fromStringz);
}
bye,
lobo
|
August 04, 2016 Re: C binding with D function | ||||
---|---|---|---|---|
| ||||
Posted in reply to bachmeier | On Wednesday, 3 August 2016 at 16:09:15 UTC, bachmeier wrote: > On Wednesday, 3 August 2016 at 15:56:34 UTC, llaine wrote: >> Okay on stack overflow, they are not using ffi but dl. >> I tried changing ffi to dl, it's the same don't work unfortunatly. > > That's about as far as I can go without having it set up on my machine. The procedure should be the same as I spelled out though. You need to create an extern(C) function that calls Runtime.initialize(). Then you call that function from Ruby the same as any other function you call with FFI. I'm familiar with the R FFI and the only difference is that some parts of that are automated. Thank's for the help. By creating two methods initialize/terminate using Runtime.initialize() it's crashing with this strange error. I looked at the core.runtime source file and I saw a C binding for thoses one : https://github.com/dlang/druntime/blob/master/src/core/runtime.d#L36 /// C interface for Runtime.initialize, returns 1/0 instead of bool extern(C) int rt_init(); /// C interface for Runtime.terminate, returns 1/0 instead of bool extern(C) int rt_term(); Any idea how can I call them ? |
August 04, 2016 Re: C binding with D function | ||||
---|---|---|---|---|
| ||||
Posted in reply to llaine | On Thursday, 4 August 2016 at 10:36:05 UTC, llaine wrote: > Any idea how can I call them ? Just like any other function. Consider this: ---------- // i.d import std.stdio; extern(C) void hello() { writeln("hi from D"); } ---------- # d.rb require 'rubygems' require 'ffi' module DInterface extend FFI::Library ffi_lib './i.so' attach_function :rt_init, :rt_init, [], :int attach_function :rt_term, :rt_term, [], :int attach_function :hello, :hello, [], :void end # call init DInterface::rt_init # our function DInterface::hello # terminate DInterface::rt_term ---------- Compile... since I have 64 bit ruby on this computer, I had to build the 64 bit .so which is a pain: dmd -shared -m64 -fPIC -defaultlib=libphobos2.so i.d Now, run the ruby: ruby ./d.rb If you have the phobos shared lib installed system wide, that should work. If not, you'll get an error about not being able to find the libphobos2.so.whatever.version. In that case, just point the path: LD_LIBRARY_PATH=/path/to/dmd2/linux/lib64 ruby ./d.rb And boom, it runs. =============== Now, you might want to make it a bit more automatic for the Ruby user. I'd do that by calling rt_init in the include file and doing an at_exit for the term. Let's also pass a string. So here's the new files: --------- // i.d import std.stdio; import std.conv; extern(C) void hello(const char* name) { // remember, it is a C function, so use C string // and convert inside writeln("hi from D, ", to!string(name)); } -------- # d.rb require 'rubygems' require 'ffi' module DInterface extend FFI::Library ffi_lib './i.so' attach_function :rt_init, :rt_init, [], :int attach_function :rt_term, :rt_term, [], :int # now taking a string attach_function :hello, :hello, [:string], :void end # call init right here for the user DInterface::rt_init # terminate automatically at_exit do DInterface::rt_term end ---------- # user.rb # this is the user code require './d' DInterface::hello 'Ruby user!' =========== Compile dmd -shared -m64 -fPIC -defaultlib=libphobos2.so i.d and run LD_LIBRARY_PATH=~/d/dmd2/linux/lib64 ruby ./user.rb hi from D, Ruby user! |
August 04, 2016 Re: C binding with D function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Thursday, 4 August 2016 at 12:14:48 UTC, Adam D. Ruppe wrote: > On Thursday, 4 August 2016 at 10:36:05 UTC, llaine wrote: >> Any idea how can I call them ? > > Just like any other function. Consider this: > > ---------- > hi from D, Ruby user! Wow thank you Adam, it's pretty impressive. I saw that your compiling using dmd with all thoses options. Can you explain me what is the benefit of using this ? I'm using just "dub" so far and its also working. Here is my repo https://github.com/llaine/ruby-dlang |
August 04, 2016 Re: C binding with D function | ||||
---|---|---|---|---|
| ||||
Posted in reply to llaine | On Thursday, 4 August 2016 at 13:14:34 UTC, llaine wrote:
> I saw that your compiling using dmd with all thoses options. Can you explain me what is the benefit of using this ?
very simple: avoiding dub. Adam is not using it.
|
Copyright © 1999-2021 by the D Language Foundation