Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
June 13, 2011 Re: Is there any convenient CopyMemory function in Phobos? | ||||
---|---|---|---|---|
| ||||
On 2011-06-13 16:27, 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).
mempcy? The C memory functions are all available in D.
- Jonathan M Davis
|
June 14, 2011 Re: Is there any convenient CopyMemory function in Phobos? | ||||
---|---|---|---|---|
| ||||
Right, haven't thought about the C functions at all (silly me). Thanks, this did the trick: extern (C) void* memcpy(void*, const void*, size_t); |
June 14, 2011 Re: Is there any convenient CopyMemory function in Phobos? | ||||
---|---|---|---|---|
| ||||
On 2011-06-13 17:01, Andrej Mitrovic wrote:
> Right, haven't thought about the C functions at all (silly me).
> Thanks, this did the trick:
> extern (C) void* memcpy(void*, const void*, size_t);
core.stdc.string has memcpy's declaration in it. You should be able to just import it rather than declaring memcpy yourself.
- Jonathan M Davis
|
June 14, 2011 Re: Is there any convenient CopyMemory function in Phobos? | ||||
---|---|---|---|---|
| ||||
So why's it in core.stdc.string, instead of say.. core.memory? Btw, I've had some imports already in the module and it seems these two conflict: import core.thread; import core.stdc.string; void main() { int* p, x; memcpy(p, x, 1); } test.d(9): Error: core.stdc.string.memcpy at D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\string.di(11) conflicts with core.thread.memcpy at D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\thread.di(37) |
June 14, 2011 Re: Is there any convenient CopyMemory function in Phobos? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | Andrej Mitrovic:
> Right, haven't thought about the C functions at all (silly me).
> Thanks, this did the trick:
> extern (C) void* memcpy(void*, const void*, size_t);
Maybe you are able to wrap that memcpy in a templated D function (named copyMemory) that does what you want in a bit safer way, that contains some static and runtime asserts, etc.
Bye,
bearophile
|
June 14, 2011 Re: Is there any convenient CopyMemory function in Phobos? | ||||
---|---|---|---|---|
| ||||
On 2011-06-13 17:38, Andrej Mitrovic wrote:
> So why's it in core.stdc.string, instead of say.. core.memory?
>
> Btw, I've had some imports already in the module and it seems these two conflict:
>
> import core.thread;
> import core.stdc.string;
>
> void main()
> {
> int* p, x;
> memcpy(p, x, 1);
> }
>
> test.d(9): Error: core.stdc.string.memcpy at
> D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\string.di(11)
> conflicts with core.thread.memcpy at
> D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\thread.di(37)
core.thread has its own private declaration of memcpy (IIRC, they don't match for some reason). Why a private declaration conflicts, I don't know. That certainly _sounds_ like a bug. Regardless, I have no clue why those declarations are where they are. I would have expected something like core.memory, but they seem to be strewn about druntime. That should probably be improved. I just grepped druntime to find where memcpy's declaration was. I don't know why it is where it is.
- Jonathan M Davis
|
June 14, 2011 Re: Is there any convenient CopyMemory function in Phobos? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis wrote: >On 2011-06-13 17:38, Andrej Mitrovic wrote: >> So why's it in core.stdc.string, instead of say.. core.memory? >> >> Btw, I've had some imports already in the module and it seems these two conflict: >> >> import core.thread; >> import core.stdc.string; >> >> void main() >> { >> int* p, x; >> memcpy(p, x, 1); >> } >> >> test.d(9): Error: core.stdc.string.memcpy at >> D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\stdc\string.di(11) >> conflicts with core.thread.memcpy at >> D:\DMD\dmd2\windows\bin\..\..\src\druntime\import\core\thread.di(37) > >core.thread has its own private declaration of memcpy (IIRC, they don't match for some reason). Why a private declaration conflicts, I don't know. That certainly _sounds_ like a bug. Regardless, I have no clue why those declarations are where they are. I would have expected something like core.memory, but they seem to be strewn about druntime. That should probably be improved. I just grepped druntime to find where memcpy's declaration was. I don't know why it is where it is. > >- Jonathan M Davis The druntime C bindings follow the names of the C header files. memcpy is in 'string.h' in C --> 'core.stdc.string' in D. -- Johannes Pfau |
June 14, 2011 Re: Is there any convenient CopyMemory function in Phobos? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johannes Pfau | On 6/14/11, Johannes Pfau <spam@example.com> wrote:
> The druntime C bindings follow the names of the C
> header files. memcpy is in 'string.h' in C --> 'core.stdc.string' in D.
I assume the reason for this was because C requires strcpy and memcpy all the time when copying strings?
|
Copyright © 1999-2021 by the D Language Foundation