Delphi CopyMemory和C ++ memcpy [英] Delphi CopyMemory vs C++ memcpy

查看:149
本文介绍了Delphi CopyMemory和C ++ memcpy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



例如,我可以编写一个客户端和一个服务器。从客户端产生一个字节数组,库接受字节数组并将其发送到服务器。我写的服务器使用相同的库做相反的事情,即处理所有的流量接收,并最终传回一个字节数组。



库定义字节数组作为结构的一部分如下...(我在Delphi中静态加载库,不要以为会有所作为,但我使用FastMM4 - 这将影响应用程序之间的内存共享模型和dll?我知道使用FastMM应该OK,也试过ShareMem没有效果)

  struct content { 
void * data;
int size;
}

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

  char * data = 你好; 
memcpy((void *)content.data(),data,strlen(data)); // last参数是length,即5
// network.sendrequest(content);
//其中content.data()返回上述指针

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

  char * data =World 
memcpy((void *)content.data(),data,strlen(data)); // last参数是length,即5
// network.sendreply(content);

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



  0x0035fdf6Hello(或以Bytes ... 72,101,108,108,111)

所以在那篇文章后,我认为C ++服务器代码是正确的,因为如果我在C ++中编写一个客户端,但是用Delphi编写的客户端替换C ++客户端不起作用。我替换memcpy与CopyMemory,我认为做同样的事情,但不知何故我的字节数组是不同的,当它到达C ++服务器...我的Delphi客户端做以下...



// lDataPointer是对
// C ++中定义的
//指针(void * data;见上文)的检索引用。图书馆。它似乎是一个有效的指针在运行时...
lContentPointer:= content.data(); // from DLL
//其中ByteArray填充了Hello的字节数据
CopyMemory(lContentPointer,@ByteArray,5); //从Exe复制到DLL
// network.sendrequest(lContentPointer);

//我在CopyMemory之前打印了字节数组,以便在发送之前检查
//的内容,即'72 101 108 108 111'

因此,来自Delphi客户端的数据显示正确,但服务器上接收的数据不正确...不知怎么Hello 108 108 111')变为

  0x003efd96h,H(或在字节104,19,44,2,72中) 

我怀疑我做错了CopyMemory ...?或者我有内存共享错误的EXE和DLL之间?我如何知道C ++网络库使用什么样的内存模型?或者我只是复制了该字节数组不正确?任何帮助非常感谢...

解决方案

  CopyMemory(lContentPointer,@ByteArray,5) ; 

错误是 ByteArray ,指向数组的第一个元素的指针。因此,您将指针的地址传递给数组的第一个元素。换句话说,你有一个额外的,杂散的间接级别。您需要

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

 c $ c> CopyMemory(lContentPointer,Pointer(ByteArray),5); 






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


OK - So I never seem to have a simple question.

I have a custom library (which is not written by me) written in C++. This library does some network comms and I just pass some data to it as a byte array and retrieve a byte array from it on the other side. The library handles all the network stuff for me the sending/receiving of data to/from client/server.

So for example, I can write a client and a server. From the client I produce a byte array, the library takes the byte array and sends it to a server. The server I've written uses the same library to do the reverse, ie handle all the receiving of traffic and eventually passes back a byte array.

The library defines the byte array as part of a struct as follows... (I'm loading the library statically in Delphi, don't think that'll make a difference, but I am using FastMM4 - is this going to affect the memory sharing model between app and dll? Far as I'm aware using FastMM should be OK, have also tried ShareMem to no avail)

struct content {
  void *data;
  int size;
}

Anyway, from my client I am attempting to send "Hello"... the accepted wisdom is that the byte array data is copied into this struct by using memcpy like so...

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 with "World". So the server replies as follows...

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

From a C++ client communicating with a C++ Server I receive this data on the server...

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

So after that essay, I think the C++ server code is correct because I can communicate correctly if I write a client in C++... But replacing the C++ client with a client written in Delphi doesn't work. I've replaced memcpy with CopyMemory, which I thought did the same thing 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 appears 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 am doing something wrong with CopyMemory...? Or have I got the memory sharing wrong between the exe and the dll? How do I know what kind of memory model the C++ networking library uses? Or have I just copied that byte array incorrectly? Any help much appreciated...

解决方案

CopyMemory(lContentPointer, @ByteArray, 5);

The error is that ByteArray is, effectively, a pointer to the first element of the array. You are thus passing the address of the pointer to the first element of the array. In other words you have an extra, spurious, 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 C standard library function. The two functions perform identical tasks and are interchangeable.

这篇关于Delphi CopyMemory和C ++ memcpy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆