June 13, 2011 Is there any convenient CopyMemory function in Phobos? | ||||
|---|---|---|---|---|
| ||||
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 Re: Is there any convenient CopyMemory function in Phobos? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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).
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply