digitalmars.D.learn - Why using wrappers for D?
- Chalix (25/25) Oct 03 2016 Hi All!
- Adam D. Ruppe (6/11) Oct 03 2016 A lot of people like the wrappers as being prettier to use since
- Chalix (16/21) Oct 03 2016 Thanks for your fast answers :)
- Adam D. Ruppe (9/12) Oct 03 2016 It is possible, you just need to match compilers with the library
- Chalix (17/26) Oct 03 2016 Ah, so the Qt libraries are C++ libraries. And they have to be
- Kagamin (4/8) Oct 03 2016 If you don't use D-specific stuff like autogenerated comparison
- Kagamin (5/9) Oct 03 2016 Qt bindings is a major undertaking, it was tried a couple of
- =?UTF-8?Q?Ali_=c3=87ehreli?= (66/72) Oct 03 2016 Many C APIs are object-oriented in that, they pass the most interesting
- rikki cattermole (16/39) Oct 03 2016 Ok lets get a few things straight.
- Chalix (8/15) Oct 03 2016 I don't know if we understand each other. You have to declare
- rikki cattermole (6/17) Oct 03 2016 Basically some features do not match up nicely like operators and
- cym13 (6/32) Oct 03 2016 D provides ways to do things that C or C++ don't provide
- Mike Parker (19/29) Oct 03 2016 A binding is just the C function declared in D:
- Chalix (20/37) Oct 03 2016 Thank you for the example, Mike!
- Jonathan M Davis via Digitalmars-d-learn (24/29) Oct 03 2016 The import statement just tells the D compiler to pull in declarations f...
- Chalix (8/35) Oct 03 2016 Ah great, now I understand it :)
- Jonathan M Davis via Digitalmars-d-learn (14/20) Oct 03 2016 #include is a _very_ inefficient way to do things. It results in the sam...
- ag0aep6g (24/48) Oct 03 2016 Not necessarily. dmd won't compile foo unless you tell it to by putting
- Chalix (3/5) Oct 03 2016 True, linking with this library instead of compiling it every
- Mike Parker (78/90) Oct 03 2016 You do have some confusion here, which Jonathan's answer should
- Mike Wey (4/39) Oct 03 2016 The gtkd-3 library contains for example the code you quoted above.
- Kagamin (3/11) Oct 03 2016 D was inspired by Java, so wrappers meant here are probably JNI
Hi All! The documentation of D (https://dlang.org/overview.html#compatibility) says: "Direct Access to C API's Not only does D have data types that correspond to C types, it provides direct access to C functions. There is no need to write wrapper functions, parameter swizzlers, nor code to copy aggregate members one by one." So, if there is no need for wrapper functions, why are there a lot of them? For example, GTK+ is a C library, with C-include files. Now there exists the GtkD (http://gtkd.org/) library, which describes itself as a wrapper of GTK+. GtkD contains the .d files (which I need for import, of course) and a seperate library (libgtkd-3.so). If D has direct Access to C API's, why do we need this the gtkd-3 lib, and not just use the gtk-3 lib? Furthermore, if there is an not very popular C library, where no wrapper function exists, would it possible to include it into a D project? Probably I have to transform all the .h to .d files, so i can "import" them instead of "include" them. But then, could I link against the C-library? I did not understand the concept of interaction between C and D, and I am a bit confused about wrapper functions and bindings for D now... Would be great if someone could make it a bit more clear to me :)
Oct 03 2016
On Monday, 3 October 2016 at 12:08:54 UTC, Chalix wrote:So, if there is no need for wrapper functions, why are there a lot of them?A lot of people like the wrappers as being prettier to use since you can turn C functions into classes and such. gtkd is an example of that.Furthermore, if there is an not very popular C library, where no wrapper function exists, would it possible to include it into a D project?Of course, it is simple, just bring over the necessary struct, constant, and function prototypes and it just works.
Oct 03 2016
On Monday, 3 October 2016 at 12:12:44 UTC, Adam D. Ruppe wrote:A lot of people like the wrappers as being prettier to use since you can turn C functions into classes and such. gtkd is an example of that.Thanks for your fast answers :) Hm, I thing I am missing some fundamentals... I read a bit about creating libraries in C++, and I found out, this is not possible, because there is no definition of the API. So you need some C "factory methods" to load C++ classes. So is it possible now by D to load a class directly, or what do you mean by "turn C functions into classes"? Also, I used the Qt library a lot with C++. But although it is a library, I have access to all the classes, like " QWidget w = new QWidget();". There is no factory method used. (This confuses me now a bit...) If its too much to explain within some sentences, maybe you know something where I could read more about it? I did not find anything myself. But I really want to understand what's going on.Of course, it is simple, just bring over the necessary struct, constant, and function prototypes and it just works.I have to try it :D
Oct 03 2016
On Monday, 3 October 2016 at 12:47:48 UTC, Chalix wrote:I read a bit about creating libraries in C++, and I found out, this is not possible, because there is no definition of the API.It is possible, you just need to match compilers with the library in C++, whereas C libraries don't need such an exact match. With your Qt library, you get a build of it that is compatible with the compiler you use to build your application (either compiling it yourself or getting it from an OS package repo where they did it for you for your OS version)you mean by "turn C functions into classes"?Wrap the C functions inside D classes. So they write D code that calls the C functions, then you use their D code.
Oct 03 2016
On Monday, 3 October 2016 at 12:54:03 UTC, Adam D. Ruppe wrote:It is possible, you just need to match compilers with the library in C++, whereas C libraries don't need such an exact match. With your Qt library, you get a build of it that is compatible with the compiler you use to build your application (either compiling it yourself or getting it from an OS package repo where they did it for you for your OS version)Ah, so the Qt libraries are C++ libraries. And they have to be compiled with the same compiler (or at least with a compiler with the same specification) I use for my application? I didn't know that, but it makes sense to me. But if there would be 2 C++ compilers on my linux system which create 2 different API's, I would need the Qt library twice on my system? One for an application compiled with the one compiler, and the other library for an application compiled with the other compiler. Since I have only 1 Qt library on my system, all linux compilers must create compatible API's, right?Wrap the C functions inside D classes. So they write D code that calls the C functions, then you use their D code.Ok, this is the same what cym13 wanted to say, right? So you can use the advantages of D? But I don't get, why I have a gtkd-3 lib. Why can't I just link against the gtk-3 lib then? I have now the headers to use the nice D stuff, but the linking should be done against the C-compiled library.
Oct 03 2016
On Monday, 3 October 2016 at 13:12:55 UTC, Chalix wrote:But I don't get, why I have a gtkd-3 lib. Why can't I just link against the gtk-3 lib then? I have now the headers to use the nice D stuff, but the linking should be done against the C-compiled library.If you don't use D-specific stuff like autogenerated comparison operators and big struct initializers, you would be able to link with C library alone.
Oct 03 2016
On Monday, 3 October 2016 at 12:47:48 UTC, Chalix wrote:Also, I used the Qt library a lot with C++. But although it is a library, I have access to all the classes, like " QWidget w = new QWidget();". There is no factory method used. (This confuses me now a bit...)Qt bindings is a major undertaking, it was tried a couple of times. As an alternative you can try Calypso https://github.com/Syniurge/Calypso which has a C++ language plugin so can read headers directly.
Oct 03 2016
On 10/03/2016 05:47 AM, Chalix wrote:what do you mean by "turn C functions into classes"?Many C APIs are object-oriented in that, they pass the most interesting object as the first parameter: // C struct struct Foo { // ... }; // Factory method (or, "constructor") Foo* make_foo(int i, double d); void free_foo(Foo** foo); int use_foo(Foo* foo, const char *str); Instead of living with C's limitations, one can define a D struct Foo and turn such function into member functions: // D struct struct FooD { // ... Foo* c_foo; // other things that go with // Factory method (or, "constructor") this(int i, double d) { c_foo = make_foo(i, d); // dispatch to C library } ~this() { free_foo(&c_foo); // dispatch to C library } void use(BarD bar) { enforce(use_foo(c_foo, "hello"); } } That's how a D wrapper of a C library may look like, which should be almost identical to how it could be done in C++.Also, I used the Qt library a lot with C++. But although it is a library, I have access to all the classes, like " QWidget w = new QWidget();". There is no factory method used. (This confuses me now a bit...)'new QWidget()' does call the constructor automatically, which D cannot do. (Although, with the recent changes in C++ interoperability, perhaps even that's doable today.) If D cannot create C++ object with the 'new' keyword, then they can use a layer of a factory method to do it: // A C++ layer extern "C" QWidget* make_QWidget() { return new QWidget(); } extern "C" void free_QWidget(QWidget* p) { delete p; } Since that function (i.e. not the "new expression" itself) is callable from D, the D code can now use the library: extern (C) { // ... QWidget* make_QWidget(); void free_QWidget(QWidget* p); } // D class class QWidgetD { QWidget* cpp_widget; this() { cpp_widget = make_QWidget(); } ~this() { free_QWidget(cpp_widget); } // ... } That's how I understand it anyway... :) Again though, this may be much easier today with the recent and ongoing improvements to C++ interoperability. Ali
Oct 03 2016
On 04/10/2016 1:08 AM, Chalix wrote:Hi All! The documentation of D (https://dlang.org/overview.html#compatibility) says: "Direct Access to C API's Not only does D have data types that correspond to C types, it provides direct access to C functions. There is no need to write wrapper functions, parameter swizzlers, nor code to copy aggregate members one by one." So, if there is no need for wrapper functions, why are there a lot of them? For example, GTK+ is a C library, with C-include files. Now there exists the GtkD (http://gtkd.org/) library, which describes itself as a wrapper of GTK+. GtkD contains the .d files (which I need for import, of course) and a seperate library (libgtkd-3.so). If D has direct Access to C API's, why do we need this the gtkd-3 lib, and not just use the gtk-3 lib? Furthermore, if there is an not very popular C library, where no wrapper function exists, would it possible to include it into a D project? Probably I have to transform all the .h to .d files, so i can "import" them instead of "include" them. But then, could I link against the C-library? I did not understand the concept of interaction between C and D, and I am a bit confused about wrapper functions and bindings for D now... Would be great if someone could make it a bit more clear to me :)Ok lets get a few things straight. To use any kind of function you must declare it, plain and simple. Any c or c++ function/class is the very much same way. Now C++ types such as classes are highly limited in D since it doesn't ugh cross over all that well (it does some weird things). These kinds of declarations are called bindings. We must have them since the D compilers don't support reading header files. Why don't they "just" support them you ask? Well simple, that's a whole new frontend that we must support... Walter is quite opposed to the idea and rightly so. So the real interesting question, why do we have wrappers around e.g. c++ libs? Simple, the original C++ code was designed for C++ and we can simply do those interfaces better. --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
Oct 03 2016
On Monday, 3 October 2016 at 12:15:10 UTC, rikki cattermole wrote:To use any kind of function you must declare it, plain and simple. Any c or c++ function/class is the very much same way. Now C++ types such as classes are highly limited in D since it doesn't ugh cross over all that well (it does some weird things).I don't know if we understand each other. You have to declare each function in the language you are programming, that is clear to me. So if you write in D, you need "D-Headers" (which are not called headers in D, i know). What do you mean with "Now C++ types such as classes are highly limited in D"?Why don't they "just" support them you ask?Yeah, that a D compiler can't read .h files is obvious to me :)
Oct 03 2016
On 04/10/2016 1:56 AM, Chalix wrote:On Monday, 3 October 2016 at 12:15:10 UTC, rikki cattermole wrote:Basically some features do not match up nicely like operators and constructors. They also do not share semantics e.g. value versus reference. --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirusTo use any kind of function you must declare it, plain and simple. Any c or c++ function/class is the very much same way. Now C++ types such as classes are highly limited in D since it doesn't ugh cross over all that well (it does some weird things).I don't know if we understand each other. You have to declare each function in the language you are programming, that is clear to me. So if you write in D, you need "D-Headers" (which are not called headers in D, i know). What do you mean with "Now C++ types such as classes are highly limited in D"?
Oct 03 2016
On Monday, 3 October 2016 at 12:08:54 UTC, Chalix wrote:Hi All! The documentation of D (https://dlang.org/overview.html#compatibility) says: "Direct Access to C API's Not only does D have data types that correspond to C types, it provides direct access to C functions. There is no need to write wrapper functions, parameter swizzlers, nor code to copy aggregate members one by one." So, if there is no need for wrapper functions, why are there a lot of them? For example, GTK+ is a C library, with C-include files. Now there exists the GtkD (http://gtkd.org/) library, which describes itself as a wrapper of GTK+. GtkD contains the .d files (which I need for import, of course) and a seperate library (libgtkd-3.so). If D has direct Access to C API's, why do we need this the gtkd-3 lib, and not just use the gtk-3 lib? Furthermore, if there is an not very popular C library, where no wrapper function exists, would it possible to include it into a D project? Probably I have to transform all the .h to .d files, so i can "import" them instead of "include" them. But then, could I link against the C-library? I did not understand the concept of interaction between C and D, and I am a bit confused about wrapper functions and bindings for D now... Would be great if someone could make it a bit more clear to me :)D provides ways to do things that C or C++ don't provide (otherwise we wouldn't be using it). C/C++ functions and structures are designed to fit well in C/C++, not in D. To make them easy to use and avoid code of mixed style we build up a facade : the wrapper. That's all.
Oct 03 2016
On Monday, 3 October 2016 at 12:08:54 UTC, Chalix wrote:Furthermore, if there is an not very popular C library, where no wrapper function exists, would it possible to include it into a D project? Probably I have to transform all the .h to .d files, so i can "import" them instead of "include" them. But then, could I link against the C-library?Yes, but here you're talking about a binding, not a wrapper.I did not understand the concept of interaction between C and D, and I am a bit confused about wrapper functions and bindings for D now... Would be great if someone could make it a bit more clear to me :)A binding is just the C function declared in D: // foo.h extern void my_func(const char *str); // foo.d extern(C) void my_func(const(char)* str) nogc nothrow; Now with the declaration in D, you can link directly to the C library. But you also need foo.d to be linked into your program, either by compiling it alongside your own source files or linking it as a library (as you do with gtkd-3.lib). A wrapper takes a C interface and makes it more D like. // wrapfoo.d import foo; // import the foo module from above void myFunc(string s) { import std.string : toStringz; my_func(s.toStringz()); }
Oct 03 2016
On Monday, 3 October 2016 at 13:51:28 UTC, Mike Parker wrote:// wrapfoo.d import foo; // import the foo module from above void myFunc(string s) { import std.string : toStringz; my_func(s.toStringz()); }Thank you for the example, Mike! And thanks to all others who support me with their answers! I didn't expect so much answers, the D community seems to be very helpful :) But there still is one thing, which I don't get: If I "import foo;" in my project, it will be compiled alongside. So there is no need for an extra library. Same should be for wrapfoo.d. If I "import wrapfoo;", I should just need the C-library "foo", and no D-library "food" right? To have a more practical example, I looked up the "header" of the GtkD gtk/Main.d file. There are functions exactly like you described:public static void init(ref string[] argv) { int argc = cast(int)argv.length; char** outargv = Str.toStringzArray(argv); gtk_init(&argc, &outargv); argv = Str.toStringArray(outargv, argc); }This function wraps the C-like gtk_init function to a D init function. The gtk_init function is the function from the GTK+ library, which is loaded in the gtkc/gtk.d file:Linker.link(gtk_init, "gtk_init", LIBRARY.GTK);Linker and link are defined in the gtkc/Loader.d So, why is it not enough just to "import gtk.Main"? What kind of code is inside the gtkd-3 library?
Oct 03 2016
On Monday, October 03, 2016 17:19:47 Chalix via Digitalmars-d-learn wrote:But there still is one thing, which I don't get: If I "import foo;" in my project, it will be compiled alongside. So there is no need for an extra library. Same should be for wrapfoo.d. If I "import wrapfoo;", I should just need the C-library "foo", and no D-library "food" right?The import statement just tells the D compiler to pull in declarations for the symbols that it needs from those modules. It doesn't actually compile those modules. You still have to give them to the compiler (either all together or separately to generate .o/.obj files) in order to actually compile them. And anything that's not D (like a C/C++ library) still needs to be linked in just like it would be in C/C++. In C/C++, #including is not enough to compile everything into your code unless everything is in the header files (which it rarely is). For the files in your project, you have to compile every .c/.cpp file to generate the .o or .obj files that the linker then links into your program, and for the 3rd party stuff that's in a library you need to link in the library. Simply #including doesn't actually bring something like curl or gtk into your program. You also have to link it when generating your executable. It's basically the same thing with D. Every .d file in your project needs to be compiled so that it gets linked into your executable, and if you want to use 3rd party stuff, you have to link in the libraries just like you would with C/C++. The separation is perhaps a bit less clear in D, because you usually just use .d files for everything, whereas C/C++ have .h and .c/.cpp as separate files. D does have .di files for the cases where you need to hide your code, but they don't get used often. But when you do use a .di file, that's what gets imported rather than the .d file which contains the actual definitions, so in that case, the separation is clearer. - Jonathan M Davis
Oct 03 2016
On Monday, 3 October 2016 at 17:45:55 UTC, Jonathan M Davis wrote:The import statement just tells the D compiler to pull in declarations for the symbols that it needs from those modules. It doesn't actually compile those modules. You still have to give them to the compiler (either all together or separately to generate .o/.obj files) in order to actually compile them. And anything that's not D (like a C/C++ library) still needs to be linked in just like it would be in C/C++. In C/C++, #including is not enough to compile everything into your code unless everything is in the header files (which it rarely is). For the files in your project, you have to compile every .c/.cpp file to generate the .o or .obj files that the linker then links into your program, and for the 3rd party stuff that's in a library you need to link in the library. Simply #including doesn't actually bring something like curl or gtk into your program. You also have to link it when generating your executable. It's basically the same thing with D. Every .d file in your project needs to be compiled so that it gets linked into your executable, and if you want to use 3rd party stuff, you have to link in the libraries just like you would with C/C++. The separation is perhaps a bit less clear in D, because you usually just use .d files for everything, whereas C/C++ have .h and .c/.cpp as separate files. D does have .di files for the cases where you need to hide your code, but they don't get used often. But when you do use a .di file, that's what gets imported rather than the .d file which contains the actual definitions, so in that case, the separation is clearer.Ah great, now I understand it :) I thought, import and include would work the same way (taking all the code in the .h or .d file and pasting it into the other file). But if import extracts only the definitions, it is clear, that you have to link against the library, or to add all the .d files to your source code. A big thank-you to all repliers for making things clear :D
Oct 03 2016
On Monday, October 03, 2016 18:05:47 Chalix via Digitalmars-d-learn wrote:Ah great, now I understand it :) I thought, import and include would work the same way (taking all the code in the .h or .d file and pasting it into the other file). But if import extracts only the definitions, it is clear, that you have to link against the library, or to add all the .d files to your source code.#include is a _very_ inefficient way to do things. It results in the same code being compiled over and over again, which is why pretty much every language post C/C++ has some sort of symbol import mechanism in attempt to compile everything only once. The way it works in D, you do end up with some amount of work being redone if you do incremental compilation, but even then, it minimizes how much it has to redo, and there are future improvements planned which will make it even better. There's a reason why D compiles so much faster than C/C++. :) You should probably read this article by Walter on why C/C++ compilation is so slow: http://www.digitalmars.com/articles/b54.html It's quite enlightening - and horrifying. - Jonathan M Davis
Oct 03 2016
On 10/03/2016 07:19 PM, Chalix wrote:If I "import foo;" in my project, it will be compiled alongside.Not necessarily. dmd won't compile foo unless you tell it to by putting foo.d on the command line. If foo is only imported, dmd parses the file but it doesn't compile it.So there is no need for an extra library.You don't *need* the library. You can just compile the file together with the rest of your program, yes. When you do precompile to a library, you can skip the compilation later. That can save time. And you can shorten the distributed D source files to just the function signatures, like with header files in C. For this, the compiler recognizes the .di filename extension. This can be used to somewhat protect closed source code. And then there are shared libraries, which are loaded at run time. Their code is not included in the executable, so you get a smaller file. Makes sense with popular libraries that are used by many programs.Same should be for wrapfoo.d. If I "import wrapfoo;", I should just need the C-library "foo", and no D-library "food" right?If wrapfoo is really just a binding, i.e. it provides only function signatures and no implementation, then there's no point in compiling it to a library. Otherwise, if wrapfoo actually implements something of its own, it can make sense to compile it to a library. Just like with every other piece of code.To have a more practical example, I looked up the "header" of the GtkD gtk/Main.d file. There are functions exactly like you described:If the GtkD files contain all the implementations (not just signatures), then you don't have to build/use the library. You can just compile the GtkD source files along with your program, and link with the C library.public static void init(ref string[] argv) { int argc = cast(int)argv.length; char** outargv = Str.toStringzArray(argv); gtk_init(&argc, &outargv); argv = Str.toStringArray(outargv, argc); }This function wraps the C-like gtk_init function to a D init function. The gtk_init function is the function from the GTK+ library, which is loaded in the gtkc/gtk.d file:Linker.link(gtk_init, "gtk_init", LIBRARY.GTK);Linker and link are defined in the gtkc/Loader.d So, why is it not enough just to "import gtk.Main"? What kind of code is inside the gtkd-3 library?
Oct 03 2016
On Monday, 3 October 2016 at 17:56:46 UTC, ag0aep6g wrote:When you do precompile to a library, you can skip the compilation later. That can save time.True, linking with this library instead of compiling it every time I changed my code will save me a lot of time :)
Oct 03 2016
On Monday, 3 October 2016 at 17:19:47 UTC, Chalix wrote:If I "import foo;" in my project, it will be compiled alongside. So there is no need for an extra library. Same should be for wrapfoo.d. If I "import wrapfoo;", I should just need the C-library "foo", and no D-library "food" right?You do have some confusion here, which Jonathan's answer should clear up (that is, importing a module does not cause it to be compiled, only makes its symbols to the module in which the declaration is made), however, there is one point I'd like to make below.This function wraps the C-like gtk_init function to a D init function. The gtk_init function is the function from the GTK+ library, which is loaded in the gtkc/gtk.d file:I don't know the details of the gtkd-3 library, but consider this example: ``` // csay.c #include <stdio.h> void sayHi() { puts("Hi\n"); } // dsay.d module dsay; extern(C) void sayHi(); // hi.d import dsay; void main() { sayHi(); } ``` Assuming you have both dmd and dmc installed, you can easily do a bit of experimentation like so: First, use dmd to generate csay.obj. dmc -c csay.c Next, with dsay.d, hi.d and csay.obj all in the same directory, build an executable. dmd hi.d csay.obj This should result in both a successful compile and a successful link. But understand that dsay.d was *never* compiled in this process. Importing dsay made the source symbol 'sayHi' available to hi.d. The compiler emitted a call to sayHi in the generated binary (hi.obj). Finally, the linker was able to match that call to the C sayHi function and could perform the link to generate the executable. Because the binary symbol for sayHi was already present in csay.obj, you did not need to compile and link dsay.d. Now, let's change it up a bit: ``` // csay.h extern void sayHi(); #define sayHiTwice \ sayHi(); \ sayHi(); ``` This is a horrible macro, but it serves its purpose as an example. In order to provide sayHiTwice in D, it will have to be implemented and not just declared: ``` // dsay.d extern(C) void sayHi(); void sayHiTwice() { sayHi(); sayHi(); } ``` Since the C version of sayHiTwice is a macro and not a function, it need not be extern(C). However, no we have an implementation and not simply a declaration. So this: ``` // hi.d import dsay; void main() { sayHiTwice(); } ``` dmd hi.d csay.obj Is now going to generate a *linker* error. It will *compile* just fine, since the import of dsay makes sayHiTwice visible during compilation. However, since csay.obj does not contain a binary symbol for sayHiTwice (as it's a macro and not a function), the the linker will be unable to match the call to any existing symbol and will produce an error. So you would have to do this: dmd hi.d dsay.d csay.obj Now, the binary symbol for sayHiTwice will be generated because dsay.d is being compiled and linked into the program. So, when you have a declarations-only module, with no function implementations or template instantiations, then it need not actually be compiled and linked into the program. In that you are correct. But, no, importing a module does not automatically compile it. And any function declarations still need an implementation somewhere if they are used in the modules you do compile.Linker.link(gtk_init, "gtk_init", LIBRARY.GTK);Linker and link are defined in the gtkc/Loader.d So, why is it not enough just to "import gtk.Main"? What kind of code is inside the gtkd-3 library?
Oct 03 2016
On 10/03/2016 07:19 PM, Chalix wrote:On Monday, 3 October 2016 at 13:51:28 UTC, Mike Parker wrote:The gtkd-3 library contains for example the code you quoted above. -- Mike Wey// wrapfoo.d import foo; // import the foo module from above void myFunc(string s) { import std.string : toStringz; my_func(s.toStringz()); }Thank you for the example, Mike! And thanks to all others who support me with their answers! I didn't expect so much answers, the D community seems to be very helpful :) But there still is one thing, which I don't get: If I "import foo;" in my project, it will be compiled alongside. So there is no need for an extra library. Same should be for wrapfoo.d. If I "import wrapfoo;", I should just need the C-library "foo", and no D-library "food" right? To have a more practical example, I looked up the "header" of the GtkD gtk/Main.d file. There are functions exactly like you described:public static void init(ref string[] argv) { int argc = cast(int)argv.length; char** outargv = Str.toStringzArray(argv); gtk_init(&argc, &outargv); argv = Str.toStringArray(outargv, argc); }This function wraps the C-like gtk_init function to a D init function. The gtk_init function is the function from the GTK+ library, which is loaded in the gtkc/gtk.d file:Linker.link(gtk_init, "gtk_init", LIBRARY.GTK);Linker and link are defined in the gtkc/Loader.d So, why is it not enough just to "import gtk.Main"? What kind of code is inside the gtkd-3 library?
Oct 03 2016
On Monday, 3 October 2016 at 12:08:54 UTC, Chalix wrote:Hi All! The documentation of D (https://dlang.org/overview.html#compatibility) says: "Direct Access to C API's Not only does D have data types that correspond to C types, it provides direct access to C functions. There is no need to write wrapper functions, parameter swizzlers, nor code to copy aggregate members one by one."D was inspired by Java, so wrappers meant here are probably JNI wrappers https://en.wikipedia.org/wiki/Java_Native_Interface
Oct 03 2016