digitalmars.D - Proper C Pointer Binding
- =?UTF-8?B?IlLDs2JlcnQgTMOhc3psw7MgUMOh?= =?UTF-8?B?bGki?= (35/35) Mar 26 2014 I am programming a new GUI widget library based on OpenGL for D.
- R (7/14) Mar 26 2014 Also I am not sure about the string casting to char * here.
- bearophile (10/27) Mar 26 2014 Generally try to avoid casts as much as possible in D 2.066,
- Mike Parker (5/35) Mar 26 2014 A big gaping hole here is that longs in C can be 32-bit or 64-bit
- ralex (15/51) Mar 26 2014 You probably want something like this:
- ralex (1/6) Mar 26 2014 That should be return f; of course.
- =?UTF-8?B?IlLDs2JlcnQgTMOhc3psw7MgUMOh?= =?UTF-8?B?bGki?= (25/25) Apr 05 2014 Thanks for the suggestions! I think then I will stay with
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (7/12) Apr 05 2014 Unfortunately not, because they then their names get mangled
I am programming a new GUI widget library based on OpenGL for D. For that I manually bind the used OpenGL functions to D and create an abstraction layer to draw things, boxes, texts, shapes, etc. http://palaes.rudanium.org/HueApp/intro.php The thing compiles nicely with SDL, FreeType, FTGL. But for the text drawing I use some pretty lame binding currently. It is a fresh part of the code and want to do it properly: C Code: unsigned long loadFont(char * path) { FTGLfont * font = FTGLloadFont(path); return (unsigned long) font; } void drawText(unsigned long font, unsigned size, char * text) { // do the text drawing here } void destroyFont(unsigned long font) { FTGLdestroyFont((FTGLfont * ) font); } D Code: extern (C) ulong loadFont(char * path); extern (C) void destroyFont(ulong font); void main() { // init screen and OpenGL setup auto font = loadFont(cast (char * ) "Arial.TTF"); scope (exit) destroyFont(font); // draw some text // close OpenGL and SDL with some second delay } This works properly, and long is surely large enough to hold a pointer in it, I could use sizet, I know that would be better. My problem is that auto font here is an ulong. Could that be wrapped into a type Font so that it only accepts assignment from other Font type but no insecure numeric caluclations and make the loadFont return that Font type, and other methods use Font as arguments?
Mar 26 2014
void main() { // init screen and OpenGL setup auto font = loadFont(cast (char * ) "Arial.TTF"); scope (exit) destroyFont(font); // draw some text // close OpenGL and SDL with some second delay }Also I am not sure about the string casting to char * here. I have been told that literals are 0 terminated, but strings usually are not. Should I in your opinion create a wrapping function in D that does convert the string to a proper char * value? And how would I do that? Thanks in advance for all the help! Róbert László Páli
Mar 26 2014
R:Generally try to avoid casts as much as possible in D 2.066, because they sometimes are wrong and the compiler is not catching your mistakes. Take a look at the toStringz function in Phobos. There is also the ".ptr" attribite of dynamic arrays. But a D string is (immutable char)[], so its ptr is (immutable char)*. Bye, bearophilevoid main() { // init screen and OpenGL setup auto font = loadFont(cast (char * ) "Arial.TTF"); scope (exit) destroyFont(font); // draw some text // close OpenGL and SDL with some second delay }Also I am not sure about the string casting to char * here. I have been told that literals are 0 terminated, but strings usually are not. Should I in your opinion create a wrapping function in D that does convert the string to a proper char * value? And how would I do that?
Mar 26 2014
On 3/26/2014 6:51 PM, "Róbert László Páli" wrote:I am programming a new GUI widget library based on OpenGL for D. For that I manually bind the used OpenGL functions to D and create an abstraction layer to draw things, boxes, texts, shapes, etc. http://palaes.rudanium.org/HueApp/intro.php The thing compiles nicely with SDL, FreeType, FTGL. But for the text drawing I use some pretty lame binding currently. It is a fresh part of the code and want to do it properly: C Code: unsigned long loadFont(char * path) { FTGLfont * font = FTGLloadFont(path); return (unsigned long) font; } void drawText(unsigned long font, unsigned size, char * text) { // do the text drawing here } void destroyFont(unsigned long font) { FTGLdestroyFont((FTGLfont * ) font); } D Code: extern (C) ulong loadFont(char * path); extern (C) void destroyFont(ulong font); void main() { // init screen and OpenGL setup auto font = loadFont(cast (char * ) "Arial.TTF"); scope (exit) destroyFont(font); // draw some text // close OpenGL and SDL with some second delay } This works properly, and long is surely large enough to hold a pointer in it, I could use sizet, I know that would be better.A big gaping hole here is that longs in C can be 32-bit or 64-bit depending on the compiler and platform. Any time you want to bind to anything using longs in C, you should import core.stdc.config and use the c_long and c_ulong types.
Mar 26 2014
On Wednesday, 26 March 2014 at 09:51:04 UTC, Róbert László Páli wrote:I am programming a new GUI widget library based on OpenGL for D. For that I manually bind the used OpenGL functions to D and create an abstraction layer to draw things, boxes, texts, shapes, etc. http://palaes.rudanium.org/HueApp/intro.php The thing compiles nicely with SDL, FreeType, FTGL. But for the text drawing I use some pretty lame binding currently. It is a fresh part of the code and want to do it properly: C Code: unsigned long loadFont(char * path) { FTGLfont * font = FTGLloadFont(path); return (unsigned long) font; } void drawText(unsigned long font, unsigned size, char * text) { // do the text drawing here } void destroyFont(unsigned long font) { FTGLdestroyFont((FTGLfont * ) font); } D Code: extern (C) ulong loadFont(char * path); extern (C) void destroyFont(ulong font); void main() { // init screen and OpenGL setup auto font = loadFont(cast (char * ) "Arial.TTF"); scope (exit) destroyFont(font); // draw some text // close OpenGL and SDL with some second delay } This works properly, and long is surely large enough to hold a pointer in it, I could use sizet, I know that would be better. My problem is that auto font here is an ulong. Could that be wrapped into a type Font so that it only accepts assignment from other Font type but no insecure numeric caluclations and make the loadFont return that Font type, and other methods use Font as arguments?You probably want something like this: struct Font { static Font opCall(string path) { Font f; f.fptr = loadFont(path.toStringz()); return s; } c_ulong fptr; } use it like this: Font arial = "Arial.TTF"; when pasing font to extern functionst that accept ulong use arial.fptr, in your (D) functions use Font.
Mar 26 2014
static Font opCall(string path) { Font f; f.fptr = loadFont(path.toStringz()); return s; }That should be return f; of course.
Mar 26 2014
Thanks for the suggestions! I think then I will stay with a wrapping struct. How would I make the extern C functions invisible for other sources? extern (C) c_ulong loadFont(char * path); extern (C) void render(c_ulong font, char * text); extern (C) void destroyFont(c_ulong font); struct Font { private: c_ulong ptr; public: this(string path) { ptr = loadFont(path.toStringz()); } void render(string text) { render(ptr, text.toStringz()); } ~this() { destroyFont(ptr); } } When released as a library I would simply not put them in the di Files, but I do not really want to use di-s for developing the lib, but generate them for release. Can I declare these extern C functions inline the methods using it?
Apr 05 2014
On Saturday, 5 April 2014 at 13:55:27 UTC, Róbert László Páli wrote:When released as a library I would simply not put them in the di Files, but I do not really want to use di-s for developing the lib, but generate them for release. Can I declare these extern C functions inline the methods using it?Unfortunately not, because they then their names get mangled incorrectly. Maybe DMD should be changed to not output private declarations, if they are not needed (i.e. don't affect struct layout, for example), then you can just declare them in a `private { }` block.
Apr 05 2014