delphi - 跨内存管理器边界传递 Delphi const 字符串参数是否安全?

标签 delphi string constants parameters

主题。我想使用字符串而不是 PChar,因为这样可以省去很多转换,但如果我这样做

procedure SomeExternalProc(s: string); external SOMEDLL_DLL;

然后在其他项目中使用非共享内存管理器实现它:

library SeparateDll;
procedure SomeExternalProc(s: string);
begin
  //a bla bla bla
  //code here code here
end;

我(正式)不保证 Delphi 不会出于任何原因决定更改字符串、修改其引用计数器、重复或唯一它或其他任何内容。例如

var InternalString: string;

procedure SomeExternalProc(s: string);
begin
  InternalString := s;
end;

Delphi 增加 refcounter 并复制一个指针,就是这样。我希望 Delphi 复制数据。由于这个原因,将参数声明为“const”是否会使其安全?如果没有,有办法做到吗?将参数声明为 PChar 似乎不是一个解决方案,因为您每次都需要转换它:

procedure SomeExternalProc(s: Pchar); forward;
procedure LocalProc;
var local_s: string;
begin
  SomeExternalProc(local_s); //<<--- incompatible types: 'string' and 'PAnsiChar'
end;

最佳答案

只要您只使用在同一版本的 Delphi 中编译的代码中的 DLL,这可能会起作用。众所周知,字符串的内部格式会在不同版本之间发生变化,并且您无法正式保证它不会再次发生变化。

如果您想避免在使用它的任何地方进行强制转换,请尝试包装该函数,如下所示:

procedure SomeExternalProc(s: Pchar); external dllname;
procedure MyExternalProc(s: string); inline;
begin
  SomeExternalProc(PChar(local_s));
end;

然后在您的代码中,您调用 MyExternalProc 而不是 SomeExternalProc,每个人都很高兴。

关于delphi - 跨内存管理器边界传递 Delphi const 字符串参数是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3178868/

相关文章:

c++ - 初始化结构中的常量数组

c# - WinRT 组件库中的公共(public)常量

mysql - Delphi ADO + MySQL + Developer Express Grid

delphi - 外部应用程序 : Check if an Outlook Folder exists

delphi - 如何在控制台应用程序中使用 TIdUDPServer?

string - Delphi:如何从字符串中获取*真实的* ASCII 代码

c++ - 删除模板函数中的常量

像 Windows 一样显示字节数的 Delphi 函数

c++ - 如何确保在 C++ 中只输出 6 位、用 0 填充的十六进制值?

java - 使用 ContentHandler 提取文件内容