use*_*591 4 dll inno-setup return-value pascalscript
我在 DLL 中有两个 C 函数,它们在定义文件中定义,并导出以在 Inno Setup 中使用。
char* __stdcall GetName()
{
return "Kishore";
}
void __stdcall getName(char* strName)
{
strcpy(strName, "Kishore");
}
Run Code Online (Sandbox Code Playgroud)
Inno Setup 代码将加载自定义 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
Run Code Online (Sandbox Code Playgroud)
如何在 Inno Setup 脚本中检索名称而不崩溃?
GetName应该返回 a const char *,但是按照写的那样就可以了。但请注意,返回这样的字符串只能适用于文字字符串常量,如上所示。您不能使用此模式返回计算的字符串值(如果您尝试这样做,它可能会崩溃或提供损坏的数据);因此getName是错误的。
另请注意,虽然 C 区分大小写,但 Pascal 不区分大小写,因此getName和GetName是 Inno 脚本中的相同函数。在上述情况下,您可能会逃脱这种情况,因为参数不同,但我不会依赖于此——您应该给它们指定不同的名称。(也不要在 C 端使用相同的名称,因为有时查找 DLL 导出时也不区分大小写。)
要返回计算出的字符串,您应该使用如下模式:
DLL代码:
void __stdcall CalculateName(char *buffer, size_t size)
{
strncpy(buffer, "whatever", size);
buffer[size-1] = 0;
}
Run Code Online (Sandbox Code Playgroud)
伊诺代码:
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);
...
Run Code Online (Sandbox Code Playgroud)
存在一些可接受的变化,例如,您可以使 DLL 函数返回实际写入缓冲区的字符数,并在后续 SetLength 中使用该值,而不是调用 Pos 来查找空终止符。
但你必须:
String类型。AnsiString或 Unicode 字符串String。这里的限制之一是一侧分配的内存必须由同一侧释放。无论从哪个方向,您都无法安全地释放在 DLL 边界“错误”一侧分配的内存。
| 归档时间: |
|
| 查看次数: |
2315 次 |
| 最近记录: |