Jump to page: 1 2 3
Thread overview
C binding with D function
Aug 03, 2016
llaine
Aug 03, 2016
bachmeier
Aug 03, 2016
llaine
Aug 03, 2016
bachmeier
Aug 03, 2016
llaine
Aug 03, 2016
llaine
Aug 03, 2016
Kagamin
Aug 03, 2016
llaine
Aug 03, 2016
llaine
Aug 04, 2016
lobo
Aug 03, 2016
bachmeier
Aug 03, 2016
llaine
Aug 03, 2016
bachmeier
Aug 04, 2016
llaine
Aug 04, 2016
Adam D. Ruppe
Aug 04, 2016
llaine
Aug 04, 2016
ketmar
Aug 04, 2016
Adam D. Ruppe
Aug 05, 2016
Adam D. Ruppe
Aug 06, 2016
Adam D. Ruppe
Aug 04, 2016
bachmeier
Aug 04, 2016
Adam D. Ruppe
Aug 04, 2016
bachmeier
Aug 05, 2016
llaine
Aug 03, 2016
bachmeier
Aug 03, 2016
Adam D. Ruppe
Aug 03, 2016
llaine
August 03, 2016
Hi guys,

I'm trying to make a bridge between D and ruby with a gem called ffi.
It's basically a loading/binding library that grab C function and make them callable from Ruby code.

As you might already understand, i'm trying to develop extensions using D and uses them in Ruby.

I tried to get the simplest example ever but nothing is working so far.

Basically here is my D code :

import std.stdio : writeln;

extern(C)
{
  void puts(string str)
  {
    writeln(str);
  }
}

void main(){ }

I'm building it using "targetType": "dynamicLibrary" on my dub.json


My problem is when I try to call it in C, it blows up with a segmentation fault.
I'm looking for here extra documentation/help on how to properly create C binding in D.

I already post an issue on FFI to seek from help, you can find here some extra informations about the C trace


https://github.com/ffi/ffi/issues/522


Any help would be welcomed!
August 03, 2016
On Wednesday, 3 August 2016 at 13:44:46 UTC, llaine wrote:
> Hi guys,
>
> I'm trying to make a bridge between D and ruby with a gem called ffi.
> It's basically a loading/binding library that grab C function and make them callable from Ruby code.
>
> As you might already understand, i'm trying to develop extensions using D and uses them in Ruby.
>
> I tried to get the simplest example ever but nothing is working so far.
>
> Basically here is my D code :
>
> import std.stdio : writeln;
>
> extern(C)
> {
>   void puts(string str)
>   {
>     writeln(str);
>   }
> }
>
> void main(){ }
>
> I'm building it using "targetType": "dynamicLibrary" on my dub.json
>
>
> My problem is when I try to call it in C, it blows up with a segmentation fault.
> I'm looking for here extra documentation/help on how to properly create C binding in D.
>
> I already post an issue on FFI to seek from help, you can find here some extra informations about the C trace
>
>
> https://github.com/ffi/ffi/issues/522
>
>
> Any help would be welcomed!

Probably because you need the D runtime. One way is to import core.runtime and call Runtime.initialize().
August 03, 2016
On Wednesday, 3 August 2016 at 13:49:36 UTC, bachmeier wrote:

> Probably because you need the D runtime. One way is to import core.runtime and call Runtime.initialize().


Where should I call this Runtime.initialize() ?


August 03, 2016
On Wednesday, 3 August 2016 at 13:44:46 UTC, llaine wrote:
>   void puts(string str)
>   {
>     writeln(str);
>   }

A D string isn't the same as a C string, so your params won't work as-is, and writeln requires the D runtime to be initialized.

Does the ruby gem have a way to automatically call a particular setup and teardown function in the library? You could make init and and finalize functions that are called. Those run the Runtime.initialized and Runtime.finalize.

Looking at their docs, I don't see an automatic one, but you could do a ruby constructor/destructor in the wrapper that does it for the end user.

For the D string, either replace it with a C char* or try defining a struct on teh ruby side to match it... but C string is probably easiest.

August 03, 2016
On Wednesday, 3 August 2016 at 14:02:12 UTC, Adam D. Ruppe wrote:
> On Wednesday, 3 August 2016 at 13:44:46 UTC, llaine wrote:
>>   void puts(string str)
>>   {
>>     writeln(str);
>>   }
>
> A D string isn't the same as a C string, so your params won't work as-is, and writeln requires the D runtime to be initialized.
>
> Does the ruby gem have a way to automatically call a particular setup and teardown function in the library? You could make init and and finalize functions that are called. Those run the Runtime.initialized and Runtime.finalize.
>
> Looking at their docs, I don't see an automatic one, but you could do a ruby constructor/destructor in the wrapper that does it for the end user.
>
> For the D string, either replace it with a C char* or try defining a struct on teh ruby side to match it... but C string is probably easiest.

Okay so your advice is to directly replace string str by char* str
and then call the runtime initialisation in my function?
August 03, 2016
On Wednesday, 3 August 2016 at 14:01:34 UTC, llaine wrote:
> On Wednesday, 3 August 2016 at 13:49:36 UTC, bachmeier wrote:
>
>> Probably because you need the D runtime. One way is to import core.runtime and call Runtime.initialize().
>
>
> Where should I call this Runtime.initialize() ?

Does the second answer to this question

http://stackoverflow.com/questions/676498/haskell-binding-with-ruby-through-ffi

help? It's Haskell, but I think the hs_init function call is equivalent to Runtime.initialize. I've never done this sort of thing with Ruby so I might be missing something.
August 03, 2016
On Wednesday, 3 August 2016 at 14:58:04 UTC, bachmeier wrote:
> On Wednesday, 3 August 2016 at 14:01:34 UTC, llaine wrote:
>> On Wednesday, 3 August 2016 at 13:49:36 UTC, bachmeier wrote:
>>
>>> Probably because you need the D runtime. One way is to import core.runtime and call Runtime.initialize().
>>
>>
>> Where should I call this Runtime.initialize() ?
>
> Does the second answer to this question
>
> http://stackoverflow.com/questions/676498/haskell-binding-with-ruby-through-ffi
>
> help? It's Haskell, but I think the hs_init function call is equivalent to Runtime.initialize. I've never done this sort of thing with Ruby so I might be missing something.


So basically I have to create wrapper.c ?
I guess my D code is not valid.

For example, if I call it directly from a C program it would also breaks for sure.

Is there any good documentation on it? I've look at the official documentation, but i'm afraid it might be too advanced for me.

August 03, 2016
On Wednesday, 3 August 2016 at 15:08:51 UTC, llaine wrote:
> On Wednesday, 3 August 2016 at 14:58:04 UTC, bachmeier wrote:


On Wednesday, 3 August 2016 at 15:08:51 UTC, llaine wrote:

by switching my file to just this



extern(C)
{
  char* foo(char* str)
  {
    return str;
  }
}


It works.
But it's really ... simple ahah I was expecting to have more advanced use.

August 03, 2016
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
August 03, 2016
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
« First   ‹ Prev
1 2 3