Writing a library

Bill Baxter dnewsgroup at billbaxter.com
Fri Feb 16 13:45:09 PST 2007


Mn wrote:
> Jarrett Billingsley Wrote:
> 
>> "Mn" <mn at mailinator.com> wrote in message 
>> news:er492f$1sti$1 at digitalmars.com...
>>> Hello World!
>>>
>>> Is it possible to write a library in D that can be used by other 
>>> programming languages? And if yes, how to do it? I can think of two ways 
>>> of "using" a lib in general:
>>>
>>> 1. The OOP way: use a class of the lib, then its functions, dunno how its 
>>> called.
>>> 2. The Un-OOP way: use a function of a lib, its called P/Invoke in C#.
>>>
>>> I am only interested in the more popular languages like C, C++, Java, C#, 
>>> PHP.
>>>
>>> Greetings and thank you.
>>> -- Mn
>> No other languages understand D calling or mangling conventions, but D can 
>> make functions with C, Windows, and Pascal calling conventions.  If you just 
>> do something like:
>>
>> extern(C) export void func(int x) { ... }
>>
>> You can then, maybe, make a DLL or something out of it which can be called 
>> from virtually any other mainstream language, since most things understand 
>> the C calling convention. 
>>
>>
> 
> So if I want to create an instance of a class, the instance being created outside but the class being inside the lib, and then the class staying alive until I somehow get rid of it (calling a function of the class) - is this possible?
> 
> Short: is it possible to export a class, not only its functions? If yes, how?
> 
> Thanks.
> -- Mn

I think what you need to do is basically to mimic the type of interface 
used by C FILE operations, if you are familiar with that.

So you will need a create() call that returns a MY_CLASS, which is 
actually just a void pointer.  In fact it will be a pointer to your 
class object, but from C land all they will know is that it's a void 
pointer.  So it will look something like:
     alias void* MY_CLASS;
     extern(C) MY_CLASS createMyClass() {
         return new MyClass;
     }

Every method of your class like
      void myMethod(float arg);
will need a plain function wrapper like
       extern(C) void myClassMyMethod(MY_CLASS self, float arg);

And they'll all be implemented mostly like
       extern(C) void myClassMyMethod(MY_CLASS self, float arg) {
            MyClass real_self = cast(MyClass)self;
            // [check that it really is a MyClass]
            real_self.myMethod(arg);
       }

And you will need a destroy call that takes a MY_CLASS, too, and calls 
the destructor.

You also have to do something about any arguments or return values that 
are not C types and convert them accordingly.  For instance if you have 
a method that returns a 'real' the C wrapper needs to cast it to double.

I'm not sure if the GC will work normally or not.  But I'm pretty sure 
you'll need to do something to startup and initialize the GC on the D 
side.  Check out WinMain in 
http://www.dsource.org/projects/minwin/browser/trunk/minwin/app.d at 
line 144.  In particular the calls to gc_init(), _minit(), _moduleCtor() 
and _moduleUnitTests().

Calling D from C/C++ is not something I have not done either, but will 
probably want to do at some point.  So I'm also very interested in 
hearing about whether you succeed.  And the above is what I was planning 
to try when I get to that point.

If you're making a DLL out of the D code, then all the functions should 
be marked 'export' also so that they get marked as callable in the DLL.

--bb



More information about the Digitalmars-d mailing list