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.

Reply via email to