Delphi CopyMemory vs C++ memcpy

" ОК " - так, кажется, не простой вопрос.

у меня есть пользовательская библиотека (которая не написана мной), написанная на C++. Эта библиотека выполняет некоторые сетевые связи, и я просто передаю ей некоторые данные в виде массива байтов и извлекаю из него массив байтов с другой стороны. Библиотека обрабатывает все сетевые материалы для меня, отправляя / получая данные на / от клиента / сервера.

так, например, я могу написать клиент и сервер. От клиента я создаю массив байтов, библиотека принимает массив байтов и отправляет его на сервер. Сервер, который я написал, использует ту же библиотеку для обратного, т. е. обрабатывает весь прием трафика и в конечном итоге передает обратно массив байтов.

библиотека определяет массив байтов как часть структуры следующим образом... (Я загружаю библиотеку статически в Delphi, не думаю, что это будет иметь значение, но я использую FastMM4 - это повлияет на модель обмена памятью между приложением и dll? Насколько я знаю, используя FastMM должен быть в порядке, также попробовали ShareMem безрезультатно)

struct content {
  void *data;
  int size;
}

в любом случае, от моего клиента я пытаюсь отправить "Привет"... общепринятая мудрость заключается в том, что данные массива байтов копируются в эту структуру с помощью 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

на моем сервере я отвечаю "World". Поэтому сервер отвечает следующим образом...

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++... Но замена клиента C++ клиентом, написанным на Delphi, не работает. Я заменил memcpy на CopyMemory, который, как я думал, сделал то же самое, но каким-то образом мой массив байтов отличается к тому времени, когда он достигает сервера 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 выглядят правильными, но данные, полученные на сервере неверный... Как-то "привет" ('72 101 108 108 111') становится

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

Я подозреваю, что делаю что-то не так с CopyMemory...? Или у меня неправильный обмен памятью между exe и dll? Как узнать, какую модель памяти использует сетевая библиотека C++? Или я просто скопировал этот массив байтов неправильно? Любая помощь очень ценится...

1 ответов


CopyMemory(lContentPointer, @ByteArray, 5);

ошибка в том, что ByteArray является, по сути, указателем на первый элемент массива. Таким образом, вы передаете адрес указателя на первый элемент массива. Другими словами, у вас есть дополнительный, поддельный уровень косвенности. Вам нужно

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

или

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

как CopyMemory vs memcpy, первый является функцией Win32 API, а последний-стандартной библиотечной функцией C. Эти две функции выполняют идентичные задачи и сменный.