June 13, 2011
Apparently in the Windows API there's a whole lot of byte-copying going around.

Here's an example:

int CALLBACK EnhMetaFileProc (HDC hdc, HANDLETABLE * pHandleTable,
                              CONST ENHMETARECORD * pEmfRecord,
                              int iHandles, LPARAM pData)
{
     ENHMETARECORD * pEmfr ;

     pEmfr = (ENHMETARECORD *) malloc (pEmfRecord->nSize) ;

     CopyMemory (pEmfr, pEmfRecord, pEmfRecord->nSize) ;

     if (pEmfr->iType == EMR_RECTANGLE)
          pEmfr->iType = EMR_ELLIPSE ;

     PlayEnhMetaFileRecord (hdc, pHandleTable, pEmfr, iHandles) ;

     free (pEmfr) ;

     return TRUE ;
}

The nSize field specifies the byte size of the structure pointed to by
pEmfRecord. The reason copying is required is because of this code:
     if (pEmfr->iType == EMR_RECTANGLE)
          pEmfr->iType = EMR_ELLIPSE ;

pEmfRecord itself is const, so new memory has to be allocated first and then the memory from pEmfRecord is copied there, and then the iType field is changed. A simple pointer dereference won't copy all the bytes, since this is one of those variable-length structure types you often see in C code.

In D I've used the slice trick to assign a byte range of data from one
memory location to another:
extern (Windows)
int EnhMetaFileProc(HDC hdc, HANDLETABLE* pHandleTable,
                    const ENHMETARECORD* pEmfRecord,
                    int iHandles, LPARAM pData)
{
    ENHMETARECORD* pEmfr;
    immutable newlength = pEmfRecord.nSize;

    pEmfr = cast(ENHMETARECORD*)GC.malloc(newlength);

    (cast(ubyte*)pEmfr)[0..newlength] = (cast(ubyte*)pEmfRecord)[0..newlength];

    if (pEmfr.iType == EMR_RECTANGLE)
        pEmfr.iType = EMR_ELLIPSE;

    PlayEnhMetaFileRecord(hdc, pHandleTable, pEmfr, iHandles);

    GC.free(pEmfr);
    return TRUE;
}

That's quite ugly.. Is there a Phobos/Druntime and maybe
platform-independent function that can do byte-memory copies in a
simple way? Something like this is what I need:
CopyBytes(dest, src, bytecount);

Btw, CopyMemory is a WinAPI specific function, but I can't even link to it (it's actually an alias to RtlCopyMemory, but it's not in kernel32.lib for some reason even though MSDN says it is).
July 05, 2013
See you need copy only if     if (pEmfRecord->iType ==
EMR_RECTANGLE).
You can cast it and check it, else you perform with old
parameters.

Something like this

       if (pEmfRecord->iType == EMR_RECTANGLE)
       {
          pEmfr->iType = EMR_ELLIPSE ;

          PlayEnhMetaFileRecord (hdc, pHandleTable, pEmfr,
iHandles) ;

          free (pEmfr) ;
      }
      else
           PlayEnhMetaFileRecord (hdc, pHandleTable, pEmfRecord,
iHandles) ;

On Monday, 13 June 2011 at 23:31:56 UTC, Andrej Mitrovic wrote:
> Apparently in the Windows API there's a whole lot of byte-copying going around.
>
> Here's an example:
>
> int CALLBACK EnhMetaFileProc (HDC hdc, HANDLETABLE * pHandleTable,
>                               CONST ENHMETARECORD * pEmfRecord,
>                               int iHandles, LPARAM pData)
> {
>      ENHMETARECORD * pEmfr ;
>
>      pEmfr = (ENHMETARECORD *) malloc (pEmfRecord->nSize) ;
>
>      CopyMemory (pEmfr, pEmfRecord, pEmfRecord->nSize) ;
>
>      if (pEmfr->iType == EMR_RECTANGLE)
>           pEmfr->iType = EMR_ELLIPSE ;
>
>      PlayEnhMetaFileRecord (hdc, pHandleTable, pEmfr, iHandles) ;
>
>      free (pEmfr) ;
>
>      return TRUE ;
> }
>
> The nSize field specifies the byte size of the structure pointed to by
> pEmfRecord. The reason copying is required is because of this code:
>      if (pEmfr->iType == EMR_RECTANGLE)
>           pEmfr->iType = EMR_ELLIPSE ;
>
> pEmfRecord itself is const, so new memory has to be allocated first
> and then the memory from pEmfRecord is copied there, and then the
> iType field is changed. A simple pointer dereference won't copy all
> the bytes, since this is one of those variable-length structure types
> you often see in C code.
>
> In D I've used the slice trick to assign a byte range of data from one
> memory location to another:
> extern (Windows)
> int EnhMetaFileProc(HDC hdc, HANDLETABLE* pHandleTable,
>                     const ENHMETARECORD* pEmfRecord,
>                     int iHandles, LPARAM pData)
> {
>     ENHMETARECORD* pEmfr;
>     immutable newlength = pEmfRecord.nSize;
>
>     pEmfr = cast(ENHMETARECORD*)GC.malloc(newlength);
>
>     (cast(ubyte*)pEmfr)[0..newlength] = (cast(ubyte*)pEmfRecord)[0..newlength];
>
>     if (pEmfr.iType == EMR_RECTANGLE)
>         pEmfr.iType = EMR_ELLIPSE;
>
>     PlayEnhMetaFileRecord(hdc, pHandleTable, pEmfr, iHandles);
>
>     GC.free(pEmfr);
>     return TRUE;
> }
>
> That's quite ugly.. Is there a Phobos/Druntime and maybe
> platform-independent function that can do byte-memory copies in a
> simple way? Something like this is what I need:
> CopyBytes(dest, src, bytecount);
>
> Btw, CopyMemory is a WinAPI specific function, but I can't even link
> to it (it's actually an alias to RtlCopyMemory, but it's not in
> kernel32.lib for some reason even though MSDN says it is).