Delphi CopyMemory vs C ++ memcpy

OK - Therefore, I never have a simple question.

I have a custom library (which is not written by me) written in C ++. This library performs some network communications, and I just pass them some data in the form of a byte array and extract from it an array of bytes on the other hand. The library processes all network materials for sending / receiving data to / from the client / server.

So, for example, I can write a client and a server. From the client I create an array of bytes, the library takes a byte array and sends it to the server. The server I wrote uses the same library to do the reverse, i.e. Handle all traffic reception and ultimately transmit an array of bytes.

The library defines the byte array as part of the structure as follows ... (I load the library statically in Delphi, I don’t think this will change the situation, but I use FastMM4 - does this affect the memory exchange model between the application and the dll? As far as I know, using FastMM should be ok, also tried ShareMem to no avail)

struct content { void *data; int size; } 

In any case, I'm trying to send "Hello" from my client ... the generally accepted wisdom is that the data in the byte array is copied to this structure using memcpy, for example ...

 char *data = "Hello"; memcpy((void *)content.data(), data, strlen(data)); // last parameter is length, ie 5 // network.sendrequest(content); // where content.data() returns the aforementioned pointer 

On my server I reply "World". Thus, the server responds as follows ...

 char *data = "World"; memcpy((void *)content.data(), data, strlen(data)); // last parameter is length, ie 5 // network.sendreply(content); 

From the C ++ client interacting with the C ++ server, I get this data on the server ...

 0x0035fdf6 "Hello" (or in Bytes... 72, 101, 108, 108, 111) 

So, after this essay, I think the C ++ server code is correct, because I can communicate correctly if I write a client in C ++ ... But replacing a C ++ client with a client written in Delphi does not work. I replaced memcpy with CopyMemory, which I thought did the same, but somehow my byte array is different by the time it reaches the C ++ server ... My Delphi client does the following ...

 // lDataPointer is a retrieved reference to the // pointer (void *data; see above) defined in the // C++ library. It appears to be a valid pointer at runtime... lContentPointer := content.data(); // from DLL // Where ByteArray is populated with byte data of "Hello" CopyMemory(lContentPointer, @ByteArray, 5); // Copy from Exe to DLL // network.sendrequest(lContentPointer); // I have printed the byte array before the CopyMemory to check // its contents before sending, which is '72 101 108 108 111' 

So, the data from the Delphi client looks correct, but the data received on the server is incorrect ... Somehow, "Hello" ('72 101 108 108 111 ') becomes

 0x003efd96 "h,H" (or in Bytes 104, 19, 44, 2, 72) 

I suspect I'm doing something wrong with CopyMemory ...? Or I was not able to exchange memory between exe and dll? How to find out which memory model the C ++ network library uses? Or did I just copy this byte array incorrectly? Any help is much appreciated ...

+8
c ++ memory delphi bytearray
source share
1 answer
 CopyMemory(lContentPointer, @ByteArray, 5); 

The error is that ByteArray is, in fact, a pointer to the first element of the array. Thus, you pass the address of the pointer to the first element of the array. In other words, you have an additional, false, level of indirection. You need

 CopyMemory(lContentPointer, @ByteArray[0], 5); 

or

 CopyMemory(lContentPointer, Pointer(ByteArray), 5); 

As for CopyMemory vs memcpy , the former is a Win32 API function, and the latter is a standard C library function. Both functions perform identical tasks and are interchangeable.

+12
source share

All Articles