首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Visual中的Delphi WideString

Visual中的Delphi WideString
EN

Stack Overflow用户
提问于 2016-04-19 18:26:31
回答 3查看 219关注 0票数 1

我正在尝试从用Delphi编写的EXE中获得信息。EXE向我传递一个指向其数据结构之一的指针:

代码语言:javascript
复制
Type
  RecordType = Record
    St:   WideString;
    Next: Pointer;
  End;

Var
  DataRec: ^RecordType;

因此,在中,我声明了一个应该类似的数据类型:

代码语言:javascript
复制
struct RecordRec
{
  BSTR St;
  void *Next;
};

RecordRec *DataRec;

Delphi说WideString与BSTR兼容,但是这不起作用。当我看到我的St在调试模式时,它说

代码语言:javascript
复制
"0x0000000000000000 <Bad Ptr>   wchar_t *"

我不知道如何在Visual中声明等效的WideString。

如果是ShortString,我会声明:

代码语言:javascript
复制
struct RecordRec
{
  BYTE StLen;
  char St[255];
  void *Next;
};

但是这对于一个WideString不起作用,我真的不认为我应该声明一个包含~2^30 (1,073,741,824)字符的变量。

我遗漏了什么?我真的希望有人能帮忙。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-04-19 20:40:22

Delphi WideString确实是BSTR的包装器,但这并不意味着原始BSTR指针可以从一个进程传递到另一个进程。在跨越进程边界时,必须对其数据进行编组。COM通常会自动处理,但手动传递原始BSTR指针则不会。

因此,如果您不能更改Delphi应用程序来为字符数据提供一个IPC安全的数据块(类似于ShortString解决方案),那么接收应用程序将不得不手动封送BSTR数据。它可以使用ReadProcessMemory()

  • 从Delphi应用程序的地址空间中读取BSTR的长度(BSTR的字符数据以4字节整数作为前缀,在wchar_t元素中指定长度)。
  • 在自己的地址空间内分配指定长度的wchar_t[]数组
  • 将Delphi应用程序地址空间中的字符数据读入自己的地址空间中的数组中。

例如(为简洁而省略的错误处理):

代码语言:javascript
复制
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...
票数 2
EN

Stack Overflow用户

发布于 2016-04-19 19:14:12

你什么都没错过。德尔福的WideString确实等同于BSTR。在调试器中看到的值是空指针。Delphi会将其视为空字符串;您可能应该以同样的方式对待它。

票数 2
EN

Stack Overflow用户

发布于 2016-04-19 19:22:09

因此,您有两个不同的过程- Delphi (DP)和VS one (VSP)。每个地址空间都有自己的地址空间,而DP中的有效指针在VSP中无效。这就是为什么<Bad Ptr> (例外?)就会出现。

顺便说一下,我注意到VSP中的地址是64位。德尔福程序也是64位吗?

您需要通过共享内存进行某种进程间通信(IPC)。

因为您可以控制服务和MFC程序,所以可以将接收到的数据保存到DLL中的命名内存映射文件中,然后MFC进程将打开它并读取数据。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36726556

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档