www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to convert these constructs to D?

reply "Gary Willoughby" <dev nomad.so> writes:
I'm porting some C headers and wondered how would i convert the 
following to D:

#define pthread_self() GetCurrentThreadId()

#define pthread_handler_t void * __cdecl

typedef void * (__cdecl *pthread_handler)(void *);

#define set_timespec_nsec(ABSTIME,NSEC) { \
   GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
   (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
   (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
}
Nov 30 2013
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
Just doing these by eyeball...

On Saturday, 30 November 2013 at 14:53:35 UTC, Gary Willoughby 
wrote:
 #define pthread_self() GetCurrentThreadId()
That's simply alias pthread_self = GetCurrentThreadId;
 #define pthread_handler_t void * __cdecl
This depends on the text replacement and won't quite translate to D. Basically, this is a find/replace that transforms "pthread_handler_t" into "extern(C) void*". But since that's an incomplete type, D won't let you alias it nor even work as a standalone mixin. I'd translate this by doing the find/replace yourself. Make sure those functions return void* and are marked as extern(C).
 typedef void * (__cdecl *pthread_handler)(void *);
This creates a name for a function pointer. In D, it'd look like: alias extern(C) void* function(void*) pthread_handler;
 #define set_timespec_nsec(ABSTIME,NSEC) { \
   GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
   (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
   (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
 }
I think the most straightforward way to do this would be either a mixin, a template, or a simple function. In any case, it will need changes at the call site too, but we can use the type system to help with that. Let's do it this way: // GetSystemTimeAsFileTime needs a pointer to FILETIME, so that // must be the type of ABSTIME in here too void set_timespec_nsec(LPFILETIME time, long nsec) { GetSystemTimeAsFileTime(time.tv.ft); // no more pointer - we force that at the call site time.tv.i64 += nsec / 100; time.max_timeout_msec = nsec / 1000000; } might have to put in casts on those math if dmd complains, I'm not sure what the right types are. But whereas the macro did everything inline, here we just take a pointer to the struct and update it that way, leading to simpler code. If you get an error about passing a FILETIME when you need a FILETIME*, this is why - the old macro did the & for us, but we can't really do that in D, so we just force the programmer to do it when used.
Nov 30 2013
parent "Gary Willoughby" <dev nomad.so> writes:
Thanks all.
Nov 30 2013
prev sibling next sibling parent =?UTF-8?B?UsOpbXkgTW91w6t6YQ==?= <remy.moueza gmail.com> writes:
For the two first ones, I would use an alias:
     alias GetCurrentThreadId pthread_self;
     alias void *  pthread_handler_t;

The third one is a function pointer alias:
     alias void * function (void *) pthread_handler;

For the last one, I am not sure, being rusty with the C preprocessor 
rules. I would use a template function:
     import core.stdc.config : c_long;

     void set_timespec_nsec (T, U) (ref T abstime, U nsec) {
        GetSystemTimeAsFileTime (& abstime.tv.ft);
        abstime.tv.i64 += cast (long) (nsec) / 100;
        abstime.max_timeout_msec = cast (c_long) (nsec /1000000);
     }
Though, with that last one, you lost the ability to get it inlined (but 
there is still the -inline computer switch if performance is a real issue).
As for the type mapping, it seems that:
  - __int64 in C corresponds to long in D
  - long in C corresponds to c_long defined in core.stdc.config.

Don't hesitate to double check all this, I may have written something wrong.

On 11/30/2013 03:53 PM, Gary Willoughby wrote:
 I'm porting some C headers and wondered how would i convert the
 following to D:

 #define pthread_self() GetCurrentThreadId()

 #define pthread_handler_t void * __cdecl

 typedef void * (__cdecl *pthread_handler)(void *);

 #define set_timespec_nsec(ABSTIME,NSEC) { \
    GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
    (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
    (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
 }
Nov 30 2013
prev sibling parent reply "Craig Dillabaugh" <craig.dillabaugh gmail.com> writes:
On Saturday, 30 November 2013 at 14:53:35 UTC, Gary Willoughby 
wrote:
 I'm porting some C headers and wondered how would i convert the 
 following to D:

 #define pthread_self() GetCurrentThreadId()

 #define pthread_handler_t void * __cdecl

 typedef void * (__cdecl *pthread_handler)(void *);

 #define set_timespec_nsec(ABSTIME,NSEC) { \
   GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
   (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
   (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
 }
Maybe you have already solved all your problems, but have you tried DStep with this header? I used it on FFTW3, which is basically one GIANT C 100 line macro, and it 'seems' to have done a great job on that. However, in other cases it just seems to have dropped some defines altogether, so your mileage may vary. Craig
Nov 30 2013
parent reply "Gary Willoughby" <dev nomad.so> writes:
On Sunday, 1 December 2013 at 03:20:49 UTC, Craig Dillabaugh 
wrote:
 On Saturday, 30 November 2013 at 14:53:35 UTC, Gary Willoughby 
 wrote:
 I'm porting some C headers and wondered how would i convert 
 the following to D:

 #define pthread_self() GetCurrentThreadId()

 #define pthread_handler_t void * __cdecl

 typedef void * (__cdecl *pthread_handler)(void *);

 #define set_timespec_nsec(ABSTIME,NSEC) { \
  GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
  (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
  (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
 }
Maybe you have already solved all your problems, but have you tried DStep with this header? I used it on FFTW3, which is basically one GIANT C 100 line macro, and it 'seems' to have done a great job on that. However, in other cases it just seems to have dropped some defines altogether, so your mileage may vary. Craig
To be honest i didn't. The last time i tried DStep i had problems with compilation. I'll take another look though. I'm basically porting all the mysql-client headers which i thought would be pretty straight forward but it's taking a little more thought than i anticipated.
Dec 01 2013
next sibling parent reply "Kozzi" <kozzi11 gmail.com> writes:
 I'm basically porting all the mysql-client headers which i 
 thought would be pretty straight forward but it's taking a 
 little more thought than i anticipated.
Can I ask why? And the part of code you are asking is from pthread headers not from mysql.
Dec 01 2013
parent reply "Gary Willoughby" <dev nomad.so> writes:
On Sunday, 1 December 2013 at 20:46:20 UTC, Kozzi wrote:
 I'm basically porting all the mysql-client headers which i 
 thought would be pretty straight forward but it's taking a 
 little more thought than i anticipated.
Can I ask why? And the part of code you are asking is from pthread headers not from mysql.
No, it's from my_pthread.h
Dec 02 2013
parent "Daniel Kozak" <kozzi11 gmail.com> writes:
On Monday, 2 December 2013 at 09:01:25 UTC, Gary Willoughby wrote:
 On Sunday, 1 December 2013 at 20:46:20 UTC, Kozzi wrote:
 I'm basically porting all the mysql-client headers which i 
 thought would be pretty straight forward but it's taking a 
 little more thought than i anticipated.
Can I ask why? And the part of code you are asking is from pthread headers not from mysql.
No, it's from my_pthread.h
Ok, my fault :)
Dec 02 2013
prev sibling parent "Craig Dillabaugh" <craig.dillabaugh gmail.com> writes:
On Sunday, 1 December 2013 at 18:51:51 UTC, Gary Willoughby wrote:
 On Sunday, 1 December 2013 at 03:20:49 UTC, Craig Dillabaugh 
 wrote:
 On Saturday, 30 November 2013 at 14:53:35 UTC, Gary Willoughby 
 wrote:
 I'm porting some C headers and wondered how would i convert 
 the following to D:

 #define pthread_self() GetCurrentThreadId()

 #define pthread_handler_t void * __cdecl

 typedef void * (__cdecl *pthread_handler)(void *);

 #define set_timespec_nsec(ABSTIME,NSEC) { \
 GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
 (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
 (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
 }
Maybe you have already solved all your problems, but have you tried DStep with this header? I used it on FFTW3, which is basically one GIANT C 100 line macro, and it 'seems' to have done a great job on that. However, in other cases it just seems to have dropped some defines altogether, so your mileage may vary. Craig
To be honest i didn't. The last time i tried DStep i had problems with compilation. I'll take another look though. I'm basically porting all the mysql-client headers which i thought would be pretty straight forward but it's taking a little more thought than i anticipated.
I think you end up with a bit nicer interface if you hand role your own, but at least DStep can take care of a good bit of the grunt work for you. I had some trouble getting it running the first time (mostly my own fault), but am now glad I made the effort.
Dec 01 2013