digitalmars.D.learn - Is there any convenient CopyMemory function in Phobos?
- Andrej Mitrovic (48/48) Jun 13 2011 Apparently in the Windows API there's a whole lot of byte-copying going ...
- annonimous (16/77) Jul 05 2013 See you need copy only if if (pEmfRecord->iType ==
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).
Jun 13 2011
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).
Jul 05 2013