如何将字符串从dll返回到inno脚本 [英] How do I return a string from dll to inno script

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

问题描述

我在DLL中定义了两个C函数,它们定义在定义文件中,并导出为在Inno设置中使用

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安装脚本中检索名称没有它崩溃?

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安装程序仅支持带有 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脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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