【发布时间】:2011-12-31 00:18:59
【问题描述】:
我仍然遇到与此处提到的相同应用程序的问题 Delphi CopyMemory vs C++ memcpy
虽然我的原始问题得到了令人满意的答案,但我很难理解随后的崩溃......
我有一个使用网络库的 delphi 应用程序和一个使用相同网络库的服务器应用程序(存在于工作的某处)。网络库似乎可以正常工作是用 C++ 编写的(不是我写的)。该库为我处理所有通信,因此我只需向该库提供一个字节数组。我可以成功地向我的服务器发送和接收数据 - 并且数据在两个方向上都是正确的。
我在帮助程序中从服务器接收数据。程序正确运行到“结束”; (毫不夸张的说)。程序结束(我在这个阶段成功地通过了所有的通信,现在只关心 Delphi),调试器将我带到 _DynArrayClear - 我的应用程序崩溃的地方。从帮助中我读到“Delphi 编译器会在适当的时候自动插入对该函数的调用。”
如果有帮助,我会添加更多背景信息...网络库填充一个字节数组,该数组在内容结构中定义为 void *data(见下文)
struct content {
void *data;
int size;
}
我相信我需要做的就是在填充这些数据后在 Delphi 中执行 CopyMemory 操作...
谁能帮我理解我做错了什么?!
// should be: function THelper.ReceiveData: TBytes; -
// but my crash happens with either a function or a procedure
procedure THelper.ReceiveData;
var
lMsg: Pointer;
lSize: Integer;
lData: TBytes;
lRecvResult: Integer;
begin
lMsg := nil;
// Remote call to receive data returns an integer indicating success
lRecvResult := lib_receive_data(lMsg, Integer(Flags));
TUtils.CheckError(lRecvResult);
SetLength(lData, 5);
CopyMemory(@lData[0], lMsg, 5); // where 5 is the length of data to copy
end; // takes me into _DynArrayClear
// The application crashes after exiting _DynArrayClear
// For clarity @@noFinalize is entered at line 20795
// I get all the way to the 'end;' at line 20801 in System.pas
//
// Then from _DynArrayClear I press F7 and immediately get access violation at 0xcdcdcdcd: read address of 0xcdcdcdcd and the following is the call stack...
:7789fada ntdll.NtQueryInformationProcess + 0x12
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
【问题讨论】:
-
我不肯定,但我认为您的问题是使用
TBytes;你试过TByteArray或PByteArray吗? -
lData 动态数组在您的过程中是本地的。当它超出范围时,即退出过程时,它会自动销毁。我还不能弄清楚为什么你会得到一个例外。
-
我已经尝试过 TByteArray 和 PByteArray... 同样的问题,这让我想知道它是否是被删除两次的 void *data 或根本没有?我疲惫的眼睛不知道这个问题的答案
-
您的过程不会从 lMsg 指向的内容中释放任何内存。那东西没问题。您是否检查过
lMsg在CopyMemory之前是否为 nil ?您是否尝试过使用try .. except拥抱 CopyMemory? -
看起来堆栈坏了。检查 C 和 Delphi 代码中
lib_receive_data声明的调用约定。
标签: c++ delphi memory bytearray