如何从DLL返回字符串到Inno Setup Pascal脚本 [英] How do I return a string from DLL to Inno Setup Pascal Script

查看:132
本文介绍了如何从DLL返回字符串到Inno Setup Pascal脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two C functions in a DLL which are defined in the definition file and are exported for using in Inno Setup.

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

Inno Setup代码将加载自定义DLL并调用函数/过程以返回名称

The Inno Setup code will load the custom DLL and call the function/procedure to return the names

{ 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脚本中检索名称

How can I retrieve the name in Inno Setup script without it crashing?

推荐答案

GetName 应该会返回 const char * ,但是按书面规定还可以。但是请注意,如上所述,返回这样的字符串仅可能适用于文字字符串常量。您不能使用此模式返回计算出的字符串值(如果尝试这样做,则可能会崩溃或提供损坏的数据);因此, getName 是错误的。

GetName should return a const char *, however it is otherwise fine as written. Note however that returning a string like this can only ever possibly work for literal string constants, as shown above. You cannot use this pattern to return a calculated string value (if you try that, it will likely crash or give corrupted data); thus getName is wrong.

还要注意,尽管C区分大小写,但Pascal并不区分大小写,因此 getName GetName 在Inno脚本中是相同的函数。在上述情况下,您可能会避免这种情况,因为参数是不同的,但我不会依靠它-您应该给它们起不同的名称。 (也不要在C端使用相同的名称,因为有时也会不区分大小写地查找DLL导出。)

Also note that while C is case sensitive, Pascal is not, so getName and GetName are the same function in the Inno script. You might be getting away with this in the above case because the parameters are different, but I wouldn't rely on that -- you should give them distinct names. (Don't use the same name on the C side either, as DLL exports are sometimes looked up case-insensitively too.)

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

To return a calculated string, you should use a pattern like this:

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查找空终止符。

A few acceptable variations exist, for example you can make the DLL function return the number of characters actually written to the buffer, and use that in the subsequent SetLength rather than calling Pos to find the null terminator.

但是您必须:


  • 确保双方都使用相同的字符串类型,即ANSI或Unicode。


    • ANSI Inno Setup仅支持 String 类型的ANSI字符串。

    • Unicode Inno安装程序支持带 AnsiString 的ANSI字符串或带 String 的Unicode字符串。

    • Ensure that both sides are using the same string types, either both ANSI or both Unicode.
      • ANSI Inno Setup supports only ANSI strings with its String type.
      • Unicode Inno Setup supports either ANSI strings with AnsiString or Unicode strings with String.

      此处的约束之一是一侧分配的内存必须由同一侧释放。您不能在任一方向上安全释放在DLL边界错误侧分配的内存。

      One of the constraints in play here is that memory allocated by one side must be freed by the same side. You cannot safely release memory allocated on the "wrong" side of the DLL boundary, in either direction.

      这篇关于如何从DLL返回字符串到Inno Setup Pascal脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆