C binding with D function

Adam D. Ruppe via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Aug 4 05:14:48 PDT 2016


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!


More information about the Digitalmars-d-learn mailing list