Inno Setup 6 不能使用带有字符串参数的 DLL 函数,而它在 Inno Setup 5 中有效
Inno Setup 6 cannot use DLL function with string parameters, while it works in Inno Setup 5
我们目前正在使用 Inno Setup 5.5.3 版构建安装程序。我打算将此版本升级到 6.1.2。
我们使用 Inno Setup 安装我们的产品。我们随安装程序一起提供许可证代码,用户在安装过程中在字段中输入许可证。
此许可证使用自定义 DLL 进行验证,并且 DLL 返回非否定结果以获得有效许可证。
此过程在 5.5.3 和 5.6.1 中运行良好,但在版本 6 中失败(使用 6.0.5 和 6.1.2 测试)。
遗憾的是,没有生成指出确切问题的日志。
此自定义 DLL 是 32 位的,是 10 多年前使用 C++ 构建的。没有计划重做这部分。有什么方法可以使用相同的 DLL 来解决问题吗?谢谢。
[Files]
Source: mydll.dll; Flags: dontcopy
// This function calls the external mydll which parses licenseCode and
// returns an integer
function getFlags( secret, licenseCode : String) : Integer;
external 'getFlags@files:mydll.dll cdecl';
function checkLicense(license : String) : Boolean;
var
secret : String;
begin
Result := False; // default is Incorrect license
license := Trim(license);
secret := <secret>
// This line calls the above getFlags function and expects to get an integer
license_flags := getFlags( secret, license);
if license_flags = -1 then begin
if not suppressMsgBox then begin
MsgBoxLog( ‘Incorrect License’)
end;
Exit;
end;
Result := True;
end;
// This is the c++ function
PS_EXPORT(int) getFlags( const char * secret, const char * license ) {
// This function is returning -1 for Inno Setup 6
// but works fine for Inno Setup 5
if (strlen(license) == 0)
return -1;
...
}
这不是 5.x 与 6.x 的问题,也不是位数问题。这是一个 Ansi 与 Unicode 问题。
在5.x中,Inno Setup有两个版本,Ansi版和Unicode版。您可能使用的是 Ansi 版本并且您的代码是为它设计的。在 6.x 中,只有 Unicode 版本。您的代码不适用于 Unicode 版本。通过升级到 6.x,您无意中也从 Ansi 升级到 Unicode。
一个快速而肮脏的解决方案是更改 getFlags
函数的声明以正确地将参数声明为 Ansi 字符串(AnsiString
类型):
function getFlags( secret, licenseCode : AnsiString) : Integer;
external 'getFlags@files:mydll.dll cdecl';
正确的解决方案是重新实现您的 DLL 以使用 Unicode 字符串(wchar_t
指针):
PS_EXPORT(int) getFlags( const wchar_t * secret, const wchar_t * license )
这是一个类似的问题:。
另见 。
我们目前正在使用 Inno Setup 5.5.3 版构建安装程序。我打算将此版本升级到 6.1.2。
我们使用 Inno Setup 安装我们的产品。我们随安装程序一起提供许可证代码,用户在安装过程中在字段中输入许可证。 此许可证使用自定义 DLL 进行验证,并且 DLL 返回非否定结果以获得有效许可证。 此过程在 5.5.3 和 5.6.1 中运行良好,但在版本 6 中失败(使用 6.0.5 和 6.1.2 测试)。
遗憾的是,没有生成指出确切问题的日志。
此自定义 DLL 是 32 位的,是 10 多年前使用 C++ 构建的。没有计划重做这部分。有什么方法可以使用相同的 DLL 来解决问题吗?谢谢。
[Files]
Source: mydll.dll; Flags: dontcopy
// This function calls the external mydll which parses licenseCode and
// returns an integer
function getFlags( secret, licenseCode : String) : Integer;
external 'getFlags@files:mydll.dll cdecl';
function checkLicense(license : String) : Boolean;
var
secret : String;
begin
Result := False; // default is Incorrect license
license := Trim(license);
secret := <secret>
// This line calls the above getFlags function and expects to get an integer
license_flags := getFlags( secret, license);
if license_flags = -1 then begin
if not suppressMsgBox then begin
MsgBoxLog( ‘Incorrect License’)
end;
Exit;
end;
Result := True;
end;
// This is the c++ function
PS_EXPORT(int) getFlags( const char * secret, const char * license ) {
// This function is returning -1 for Inno Setup 6
// but works fine for Inno Setup 5
if (strlen(license) == 0)
return -1;
...
}
这不是 5.x 与 6.x 的问题,也不是位数问题。这是一个 Ansi 与 Unicode 问题。
在5.x中,Inno Setup有两个版本,Ansi版和Unicode版。您可能使用的是 Ansi 版本并且您的代码是为它设计的。在 6.x 中,只有 Unicode 版本。您的代码不适用于 Unicode 版本。通过升级到 6.x,您无意中也从 Ansi 升级到 Unicode。
一个快速而肮脏的解决方案是更改 getFlags
函数的声明以正确地将参数声明为 Ansi 字符串(AnsiString
类型):
function getFlags( secret, licenseCode : AnsiString) : Integer;
external 'getFlags@files:mydll.dll cdecl';
正确的解决方案是重新实现您的 DLL 以使用 Unicode 字符串(wchar_t
指针):
PS_EXPORT(int) getFlags( const wchar_t * secret, const wchar_t * license )
这是一个类似的问题:
另见