Delphi CopyMemory vs C ++ memcpy

时间:2011-12-29 18:22:59

标签: c++ delphi memory bytearray

好的 - 所以我似乎从来没有一个简单的问题。

我有一个用C ++编写的自定义库(不是我编写的)。这个库做了一些网络通信,我只是将一些数据作为字节数组传递给它,并在另一侧从它中检索一个字节数组。该库处理所有网络内容,以便向/从客户端/服务器发送/接收数据。

例如,我可以编写客户端和服务器。从客户端我生成一个字节数组,该库获取字节数组并将其发送到服务器。我编写的服务器使用相同的库来执行相反的操作,即处理所有流量接收并最终传回一个字节数组。

库将字节数组定义为结构的一部分,如下所示...(我在Delphi中静态加载库,不要认为这会有所作为,但我使用的是FastMM4 - 这是不是影响app和dll之间的内存共享模型?我知道使用FastMM应该没关系,也试过ShareMem无济于事了)

struct content {
  void *data;
  int size;
}

无论如何,从我的客户端我试图发送“Hello”...接受的智慧是字节数组数据通过使用memcpy复制到这个结构中...

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

在我的服务器上,我回复“世界”。所以服务器回复如下......

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

从与C ++服务器通信的C ++客户端,我在服务器上收到这些数据......

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

在那篇文章之后,我认为C ++服务器代码是正确的,因为如果我用C ++编写客户端,我可以正确地进行通信......但用Delphi编写的客户端替换C ++客户端是行不通的。我已经用CopyMemory替换了memcpy,我认为它做了同样的事情但不知何故我的字节数组在到达C ++服务器时有所不同...我的Delphi客户端执行以下操作...

// 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'

因此来自Delphi客户端的数据显示正确,但服务器上收到的数据不正确......不知何故“Hello”('72 101 108 108 111')变为

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

我怀疑我在使用CopyMemory做错了什么......?或者我有exe和DLL之间的内存共享错误?我如何知道C ++网络库使用哪种内存模型?或者我刚刚错误地复制了该字节数组?任何帮助非常感谢...

1 个答案:

答案 0 :(得分:12)

CopyMemory(lContentPointer, @ByteArray, 5);

错误是ByteArray实际上是指向数组第一个元素的指针。因此,您将指针的地址传递给数组的第一个元素。换句话说,你有一个额外的,虚假的,间接的水平。你需要

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

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

对于CopyMemory vs memcpy,前者是Win32 API函数,后者是C标准库函数。这两个函数执行相同的任务并且可以互换。