我正在尝试从用Delphi编写的EXE中获得信息。EXE向我传递一个指向其数据结构之一的指针:
Type
RecordType = Record
St: WideString;
Next: Pointer;
End;
Var
DataRec: ^RecordType;因此,在中,我声明了一个应该类似的数据类型:
struct RecordRec
{
BSTR St;
void *Next;
};
RecordRec *DataRec;Delphi说WideString与BSTR兼容,但是这不起作用。当我看到我的St在调试模式时,它说
"0x0000000000000000 <Bad Ptr> wchar_t *"我不知道如何在Visual中声明等效的WideString。
如果是ShortString,我会声明:
struct RecordRec
{
BYTE StLen;
char St[255];
void *Next;
};但是这对于一个WideString不起作用,我真的不认为我应该声明一个包含~2^30 (1,073,741,824)字符的变量。
我遗漏了什么?我真的希望有人能帮忙。
发布于 2016-04-19 20:40:22
Delphi WideString确实是BSTR的包装器,但这并不意味着原始BSTR指针可以从一个进程传递到另一个进程。在跨越进程边界时,必须对其数据进行编组。COM通常会自动处理,但手动传递原始BSTR指针则不会。
因此,如果您不能更改Delphi应用程序来为字符数据提供一个IPC安全的数据块(类似于ShortString解决方案),那么接收应用程序将不得不手动封送BSTR数据。它可以使用ReadProcessMemory():
BSTR的长度(BSTR的字符数据以4字节整数作为前缀,在wchar_t元素中指定长度)。wchar_t[]数组例如(为简洁而省略的错误处理):
RecordRec *DataRec = ...;
std::wstring DataSt;
if (DataRec->St)
{
HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, TheDelphiAppProcessID);
int len = 0;
SIZE_T numRead = 0;
ReadProcessMemory(hProcess, LPBYTE(DataRec->St)-4, &len, 4, &numRead);
if (len > 0)
{
DataSt.resize(len);
ReadProcessMemory(hProcess, DataRec->St, &DataSt[0], len*2, &numRead);
}
CloseHandle(hProcess);
}
// use DataSt as needed...发布于 2016-04-19 19:14:12
你什么都没错过。德尔福的WideString确实等同于BSTR。在调试器中看到的值是空指针。Delphi会将其视为空字符串;您可能应该以同样的方式对待它。
发布于 2016-04-19 19:22:09
因此,您有两个不同的过程- Delphi (DP)和VS one (VSP)。每个地址空间都有自己的地址空间,而DP中的有效指针在VSP中无效。这就是为什么<Bad Ptr> (例外?)就会出现。
顺便说一下,我注意到VSP中的地址是64位。德尔福程序也是64位吗?
您需要通过共享内存进行某种进程间通信(IPC)。
因为您可以控制服务和MFC程序,所以可以将接收到的数据保存到DLL中的命名内存映射文件中,然后MFC进程将打开它并读取数据。
https://stackoverflow.com/questions/36726556
复制相似问题