dll - 如何将字符串从 DLL 返回到 Inno Setup Pascal 脚本

标签 dll inno-setup return-value pascalscript

我在 DLL 中有两个 C 函数,它们在定义文件中定义并导出以在 Inno Setup 中使用。

char* __stdcall GetName()
{
        return "Kishore";
}
void __stdcall getName(char* strName)
{
     strcpy(strName, "Kishore");
}

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

如何在不崩溃的情况下检索 Inno Setup 脚本中的名称?

最佳答案

GetName应该返回 const char * ,但是其他方面都很好。但是请注意,返回这样的字符串可能只适用于文字字符串常量,如上所示。您不能使用此模式返回计算出的字符串值(如果您尝试这样做,它可能会崩溃或提供损坏的数据);因此getName是错的。

另请注意,虽然 C 区分大小写,但 Pascal 不区分大小写,所以 getNameGetName在 Inno 脚本中是相同的功能。在上述情况下,您可能会逃脱,因为参数不同,但我不会依赖于此——您应该给它们指定不同的名称。 (也不要在 C 端使用相同的名称,因为有时查找 DLL 导出也不区分大小写。)

要返回计算出的字符串,您应该使用这样的模式:

DLL代码:

void __stdcall CalculateName(char *buffer, size_t size)
{
    strncpy(buffer, "whatever", size);
    buffer[size-1] = 0;
}

创新代码:
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 仅支持 ANSI 字符串及其 String类型。
  • Unicode Inno Setup 支持带有 AnsiString 的 ANSI 字符串。或带有 String 的 Unicode 字符串.
  • 使用 Unicode 字符串时,请确保双方同意 Max 和/或返回值是以字符还是字节指定(示例代码假定以字符为单位)。
  • 在调用该函数之前,使用 SetLength 或 StringOfChar 来确保缓冲区的大小已达到所需的最大可能结果长度。
  • 确保被调用的函数不会尝试写入超过此最大长度(如果将其作为函数的参数提供,则更容易)。
  • 确保如果您使用 Pos,则被调用的函数必须确保该值以 null 结尾(或者您需要比示例中显示的更小心)。
  • 确保在调用后将字符串截断为实际长度,方法是使用返回值或查找空终止符。

  • 这里的限制之一是一侧分配的内存必须由同一侧释放。您不能安全地释放在 DLL 边界“错误”一侧分配的内存,无论是哪个方向。

    关于dll - 如何将字符串从 DLL 返回到 Inno Setup Pascal 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21574264/

    相关文章:

    c - 使用 C 代码构建 R 包,缺少 dll

    c++ - 逆向工程 C++ DLL

    visual-studio - 设置 Inno 以运行 Office 加载项安装程序并等待它

    c# - 如何正确捕获调用存储过程的返回值

    java - 运行DLL中声明的方法的代码

    c++ - 如何在 DLL 之间共享类

    postgresql - 将 Inno Setup exec 函数中的命令传递到 pgsql 数据库中

    inno-setup - 如何从 ini 文件在 Inno 设置中设置 DefaultDirName?

    java - 在Eclipse中调试时,我可以在返回之前找出返回值吗?

    c# - 如何指示何时故意忽略返回值