SUBJ。我想使用字符串而不是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;
答案 0 :(得分:13)
这可能会有效,只要您只使用在相同版本的Delphi中编译的代码中的DLL。已知字符串的内部格式会在不同版本之间发生变化,并且您无法保证它不会再次更改。
如果您想避免在任何地方使用它,请尝试包装该功能,如下所示:
procedure SomeExternalProc(s: Pchar); external dllname;
procedure MyExternalProc(s: string); inline;
begin
SomeExternalProc(PChar(local_s));
end;
然后在您的代码中,您拨打MyExternalProc
而不是SomeExternalProc
,并且每个人都很高兴。
答案 1 :(得分:6)
如果应用程序和DLL都是在同一个Delphi版本中编写的,只需使用共享内存管理器(更多详细信息here)。
如果一方用不同的语言编写,除了使用PChar或WideString之外别无其他方式(WideStrings由COM内存管理器管理)。
或者您可以编写包装函数:
procedure MyExternalProc(const s: string);
begin
SomeExternalProc(PChar(s));
end;
答案 2 :(得分:0)
只是添加一个事实:
Delphi允许您简单地将PChar分配给字符串,因此在DLL端您不需要任何类型转换:
function MyDllFunction(_s: PChar): integer;
var
s: string;
begin
s := _s; // implicit conversion to string
// now work with s instead of the _s parameter
end;
这也适用于将PChar作为参数传递给期望(按值)字符串的函数。
答案 3 :(得分:-1)
我建议使用替代内存管理器,例如RecyclerMM或FastMM。它们不需要任何外部共享MM dll,并允许您安全地将字符串传递给dll。作为奖励,您可以在整个应用程序中获得良好的性能提升。
FastMM在Delphi 2006及更高版本中用作默认内存管理器。它也是搜索内存泄漏的好工具。