char* __stdcall GetName() { return "Kishore"; } void __stdcall getName(char* strName) { strcpy(strName,"Kishore"); }
Inno安装代码将加载自定义DLL并调用函数/过程以返回名称
{ Inno Setup script } [Code] procedure getName(MacAddress: String); external 'getName@files:MyDll.dll stdcall setuponly'; function GetName():PAnsiChar; external 'GetName@files:MyDll.dll stdcall setuponly'; function NextButtonClick(CurPage: Integer): Boolean; var StrName: String; begin SetLength(StrName,15); getName(StrName); { displaying only single character } StrName := GetName(); { this call is crashing } end
如何在Inno安装脚本中检索名称而不会崩溃?
另请注意,虽然C区分大小写,但Pascal不是,因此getName和GetName在Inno脚本中是相同的功能.在上面的例子中你可能会因为参数不同而侥幸逃脱,但我不会依赖它 – 你应该给它们不同的名字. (也不要在C端使用相同的名称,因为DLL导出有时也会不区分大小写.)
要返回计算字符串,您应该使用如下模式:
DLL代码:
void __stdcall CalculateName(char *buffer,size_t size) { strncpy(buffer,"whatever",size); buffer[size-1] = 0; }
Inno代码:
procedure CalculateName(Buffer: AnsiString; Max: Cardinal); external 'CalculateName@files:my.dll stdcall'; ... Max := 16; Buffer := StringOfChar(#0,Max); CalculateName(Buffer,Max); SetLength(Buffer,Pos(#0,Buffer) - 1); ...
存在一些可接受的变体,例如,您可以使DLL函数返回实际写入缓冲区的字符数,并在随后的SetLength中使用它而不是调用Pos来查找空终止符.
但你必须:
>确保双方使用相同的字符串类型,ANSI或Unicode.
> ANSI Inno Setup仅支持具有String类型的ANSI字符串.
> Unicode Inno Setup支持带有AnsiString的ANSI字符串或带有String的Unicode字符串.
>使用Unicode字符串时,请确保双方同意是否以字符或字节指定Max和/或返回值(示例代码假定它以字符为单位).
>在调用函数之前,使用SetLength或StringOfChar确保缓冲区的大小已达到所需的最大可能结果长度.
>确保被调用函数不会尝试写入超过此最大长度(如果将其作为函数的参数提供,则更容易).
>确保如果您使用Pos,则被调用函数必须确保该值以空值终止(或者您需要比示例中所示更加小心).
>确保在调用之后将字符串截断为实际长度,方法是使用返回值或查找空终止符.
这里的约束之一是由一侧分配的存储器必须由同一侧释放.您无法在任一方向上安全地释放在DLL边界的“错误”侧分配的内存.
原文地址:https://www.jb51.cc/windows/371609.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。