www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Writing a library

reply Mn <mn mailinator.com> writes:
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
Feb 16 2007
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Mn" <mn mailinator.com> wrote in message 
news:er492f$1sti$1 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.
Feb 16 2007
next sibling parent Mn <mn mailinator.com> writes:
Jarrett Billingsley Wrote:

 "Mn" <mn mailinator.com> wrote in message 
 news:er492f$1sti$1 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.
Thanks for your reply. But if I now want - for example - to have three functions: openSomething(...) { connection c = pointer to an opened file } doSomething(...) { do something with c } closeSomething(...) { close connection c } How do I pass the c between these three functions? How do I ensure that c stays alive until I call closeSomething(...), and then how do I remove it? Next problem (?) is that it has to be possible to call openSomething multiple times, use doSomething with the right c multiple times and then close all the c. Sure i can just return a pointer from openSomething and pass it over to doSomething and closeSomething - but to what shall this pointer point? And where to store that? I need something persistant in the lib. How to do this? Thanks for your help. -- Mn
Feb 16 2007
prev sibling next sibling parent reply David Gileadi <foo bar.com> writes:
Jarrett Billingsley wrote:
 "Mn" <mn mailinator.com> wrote in message 
 news:er492f$1sti$1 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.
I tried this very thing about a year ago, creating a DLL in D with extern(C) functions which was imported and called by a C# program. It passed data back and forth via simple structs, defined on both the C# and D side. It worked great when called via a D host, but would segfault every time I tried it from the C# host. I never did figure out what was going on (and since it was a school project I just gave up and ported the code to C#). I suspected it was the fault of the garbage collector running in a separate thread, and at the time the calls to disable/enable the GC didn't do anything, so I didn't get to test if my suspicion was true. I'd be very interested to hear of your success with this.
Feb 16 2007
parent reply Mn <mn mailinator.com> writes:
David Gileadi Wrote:

 Jarrett Billingsley wrote:
 "Mn" <mn mailinator.com> wrote in message 
 news:er492f$1sti$1 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.
I tried this very thing about a year ago, creating a DLL in D with extern(C) functions which was imported and called by a C# program. It passed data back and forth via simple structs, defined on both the C# and D side. It worked great when called via a D host, but would segfault every time I tried it from the C# host. I never did figure out what was going on (and since it was a school project I just gave up and ported the code to C#). I suspected it was the fault of the garbage collector running in a separate thread, and at the time the calls to disable/enable the GC didn't do anything, so I didn't get to test if my suspicion was true. I'd be very interested to hear of your success with this.
You said you wrote a DLL in D and tried to access it via C#, ok. But what do you mean with "D host" and "C# host" then?? Accessing a .NET Assembly is unlikely to be possible that easy from D, although C# offers COM support. I will post a seperate reply for this topic. As far as I know there is a way to disable GC for parts of or the whole program. I will of course continue to look into this, but as of now I just started with D. Although it looks wonderful and its steep learning curve should be conquered in zero time.
Feb 16 2007
parent David Gileadi <foo bar.com> writes:
Mn wrote:
 David Gileadi Wrote:
 
 Jarrett Billingsley wrote:
 "Mn" <mn mailinator.com> wrote in message 
 news:er492f$1sti$1 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.
I tried this very thing about a year ago, creating a DLL in D with extern(C) functions which was imported and called by a C# program. It passed data back and forth via simple structs, defined on both the C# and D side. It worked great when called via a D host, but would segfault every time I tried it from the C# host. I never did figure out what was going on (and since it was a school project I just gave up and ported the code to C#). I suspected it was the fault of the garbage collector running in a separate thread, and at the time the calls to disable/enable the GC didn't do anything, so I didn't get to test if my suspicion was true. I'd be very interested to hear of your success with this.
You said you wrote a DLL in D and tried to access it via C#, ok. But what do you mean with "D host" and "C# host" then?? Accessing a .NET Assembly is unlikely to be possible that easy from D, although C# offers COM support. I will post a seperate reply for this topic. As far as I know there is a way to disable GC for parts of or the whole program. I will of course continue to look into this, but as of now I just started with D. Although it looks wonderful and its steep learning curve should be conquered in zero time.
Maybe "host" wasn't the best choice of words. I meant the .exe which loads the DLL and calls the code--i.e. in this case the C# program was the "host". I also had a program written in D to call the code in the DLL. I never tried to load a DLL written in C# from D code--as you say, this is not likely possible, at least not without some massive effort.
Feb 16 2007
prev sibling parent reply Mn <mn mailinator.com> writes:
Jarrett Billingsley Wrote:

 "Mn" <mn mailinator.com> wrote in message 
 news:er492f$1sti$1 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.
Is it possible to use the COM with D?
Feb 16 2007
next sibling parent BCS <BCS pathlink.com> writes:
Mn wrote:
 
 
 Is it possible to use the COM with D?
http://www.digitalmars.com/d/interface.html at the bottom
Feb 16 2007
prev sibling parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Mn wrote:
 Is it possible to use the COM with D?
Yes. The last section of http://www.digitalmars.com/d/interface.html : --- COM Interfaces A variant on interfaces is the COM interface. A COM interface is designed to map directly onto a Windows COM object. Any COM object can be represented by a COM interface, and any D object with a COM interface can be used by external COM clients. A COM interface is defined as one that derives from the interface std.c.windows.com.IUnknown. A COM interface differs from a regular D interface in that: * It derives from the interface std.c.windows.com.IUnknown. * It cannot be the argument of a DeleteExpression. * References cannot be upcast to the enclosing class object, nor can they be downcast to a derived interface. To accomplish this, an appropriate QueryInterface() would have to be implemented for that interface in standard COM fashion. ---
Feb 16 2007
prev sibling next sibling parent reply Mn <mn mailinator.com> writes:
Jarrett Billingsley Wrote:

 "Mn" <mn mailinator.com> wrote in message 
 news:er492f$1sti$1 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
Feb 16 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Mn wrote:
 Jarrett Billingsley Wrote:
 
 "Mn" <mn mailinator.com> wrote in message 
 news:er492f$1sti$1 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
Feb 16 2007
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message 
news:er58l2$i21$1 digitalmars.com...
 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().
The GC should work normally, but one thing you have to do is to make sure you keep references to any GC memory (i.e. anything allocated with 'new' in your D code) in the DLL. One way of doing this for classes is to keep a static list or AA of all instances of the class in the class: class ExportedClass { static bool[ExportedClass] instances; this() { .... instances[this] = true; } ~this() { instances.remove(this); } } This way, there is at least one reference to each class instance held in the DLL, so that the instances won't get collected. When the instances are deleted, they are removed from the list.
Feb 16 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Jarrett Billingsley wrote:
 "Bill Baxter" <dnewsgroup billbaxter.com> wrote in message 
 news:er58l2$i21$1 digitalmars.com...
 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().
The GC should work normally, but one thing you have to do is to make sure you keep references to any GC memory (i.e. anything allocated with 'new' in your D code) in the DLL. One way of doing this for classes is to keep a static list or AA of all instances of the class in the class: class ExportedClass { static bool[ExportedClass] instances; this() { .... instances[this] = true; } ~this() { instances.remove(this); } } This way, there is at least one reference to each class instance held in the DLL, so that the instances won't get collected. When the instances are deleted, they are removed from the list.
Ok, I wasn't sure about that. But it makes sense now. D memory allocated with 'new' is in some big D gc pool, and that's the only memory the GC scans for outstanding references. Well, that and stuff on the D stack. Anything in C land won't be noticed by the GC. Makes sense. --bb
Feb 16 2007
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
Bill Baxter wrote:
 
 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().
And please be aware that the necessary sequence of function calls is different for GDC. Fixing this has been on my "to do" list for Tango since the project began, and it really all just comes down to finding an appropriate pair of function names. They will most likely be cr_init() and cr_term(), and will call the normal runtime initialization and termination process. I think I haven't gotten around to it yet simply because no one has complained about it :-) Sean
Feb 16 2007
parent Mn <mn mailinator.com> writes:
Sean Kelly Wrote:
 I think I haven't gotten around to it yet simply 
 because no one has complained about it :-)
*complain*
Feb 17 2007
prev sibling next sibling parent Mn <mn mailinator.com> writes:
Bill Baxter Wrote:
 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.
The function wrapper goes inside of the class too, doesnt it? --Mn
Feb 17 2007
prev sibling next sibling parent reply Mn <mn mailinator.com> writes:
Jarrett Billingsley Wrote:

One way of doing this for classes is to keep a 
 static list or AA of all instances of the class in the class:
 
 class ExportedClass
 {
     static bool[ExportedClass] instances;
 
     this()
     {
         ....
         instances[this] = true;
     }
 
     ~this()
     {
         instances.remove(this);
     }
 }
 
But now if I somehow call a create()-function (or however i call it) it creates a class instance and returns it. The class adds a reference to that instance to its instances list. But then we return from that create() function to the program outside of the lib/dll - and the instances list? Doesnt it get removed by GC? How long does it (the instances list) stay in memory (or wherever it is)? From first call to OS shutdown? Or to host app shutdown? Or to ________ ? --Mn
Feb 17 2007
parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Mn wrote:
 Jarrett Billingsley Wrote:
 
 One way of doing this for classes is to keep a 
 static list or AA of all instances of the class in the class:

 class ExportedClass
 {
     static bool[ExportedClass] instances;

     this()
     {
         ....
         instances[this] = true;
     }

     ~this()
     {
         instances.remove(this);
     }
 }
But now if I somehow call a create()-function (or however i call it) it creates a class instance and returns it. The class adds a reference to that instance to its instances list. But then we return from that create() function to the program outside of the lib/dll - and the instances list? Doesnt it get removed by GC? How long does it (the instances list) stay in memory (or wherever it is)? From first call to OS shutdown? Or to host app shutdown? Or to ________ ?
It's a static variable in a DLL, so it stays in memory from the time the DLL is loaded to when it's unloaded (which may be at application shutdown if it's never explicitly unloaded).
Feb 17 2007
prev sibling parent Mn <mn mailinator.com> writes:
Mn Wrote:
 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
Just a pointer for myself: http://www.digitalmars.com/d/dll.html DLLs are for Windows afaik, what do I use under Linux?
Feb 17 2007