从非unicode Delphi调用GetStringTypeW(7)

从非unicode Delphi调用GetStringTypeW(7),delphi,winapi,localization,delphi-7,Delphi,Winapi,Localization,Delphi 7,我正试图从非unicode delphi应用程序调用GetStringTypeW,无论我做什么,我都会返回错误\u无效\u标志。我也找不到该函数的任何代码示例 我还必须重新定义函数头,因为windows.pas中提供的函数头错误地将第三个参数标识为布尔值,这是一个INT 以下是我对该函数的定义: function GetStringTypeW(dwInfoType: DWORD; lpSrcStr: PWideChar; cchSrc: Integer; lpCharType: Pointer)

我正试图从非unicode delphi应用程序调用GetStringTypeW,无论我做什么,我都会返回错误\u无效\u标志。我也找不到该函数的任何代码示例

我还必须重新定义函数头,因为windows.pas中提供的函数头错误地将第三个参数标识为布尔值,这是一个INT

以下是我对该函数的定义:

function GetStringTypeW(dwInfoType: DWORD; lpSrcStr: PWideChar; cchSrc: Integer; lpCharType: Pointer): BOOL;
GetStringTypeW(CT_CTYPE1, PWideChar(APassword), Length(APassword), PWordArray(aCharType))
由于某些原因,该函数没有定义为stdcall。尝试将其定义为stdcall将导致访问冲突

我的电话:

var
  aCharType: Array of WORD;
  APassword: WideString
begin
{..}
    SetLength(aCharType, Length(APassword));
    if not GetStringTypeW(CT_CTYPE1, PWideChar(APassword[1]), Length(APassword), @aCharType[0]) then
      RaiseLastOSError;
{..}
我得到的错误是

System Error.  Code: 1004.
Invalid flags.
我已经验证了CT_CTYPE1等于1


是否有人知道什么地方可能出错,或者有使用此函数的代码示例?

您的第二个参数出错。您正在将单个WideChar值强制转换为PWideChar,而不是获取该WideChar的内存地址。换言之,改变这一点:

PWideChar(APassword[1])
为此:

PWideChar(APassword)
或者仅当密码的长度从不为0时:

@APassword[1]

您的第二个参数是错误的。您正在将单个WideChar值强制转换为PWideChar,而不是获取该WideChar的内存地址。换言之,改变这一点:

PWideChar(APassword[1])
为此:

PWideChar(APassword)
或者仅当密码的长度从不为0时:

@APassword[1]
Windows.pas中的声明确实是错误的,但您的更正也是错误的。您已经修复了参数类型,但需要修复调用约定。它应该是stdcall:

在没有调用约定修复的情况下,Delphi将大多数参数放在寄存器中,但操作系统希望在堆栈中找到它们。堆栈在正确的位置不包含正确的值,因此失败。错误的调用约定也可能导致访问冲突,因为堆栈处于不一致的状态,但由于您立即抛出自己的异常,这可能会隐藏堆栈问题

当您使用stdcall时,会出现访问冲突,因为您正在传递一个字符并声称它是指针。操作系统尝试取消对指针的引用,但由于字符值不代表有效地址,因此操作失败。调用函数时,键入并强制转换整个字符串,而不仅仅是一个字符:

function GetStringTypeW(dwInfoType: DWORD; lpSrcStr: PWideChar; cchSrc: Integer; lpCharType: Pointer): BOOL;
GetStringTypeW(CT_CTYPE1, PWideChar(APassword), Length(APassword), PWordArray(aCharType))
Windows.pas中的声明确实是错误的,但您的更正也是错误的。您已经修复了参数类型,但需要修复调用约定。它应该是stdcall:

在没有调用约定修复的情况下,Delphi将大多数参数放在寄存器中,但操作系统希望在堆栈中找到它们。堆栈在正确的位置不包含正确的值,因此失败。错误的调用约定也可能导致访问冲突,因为堆栈处于不一致的状态,但由于您立即抛出自己的异常,这可能会隐藏堆栈问题

当您使用stdcall时,会出现访问冲突,因为您正在传递一个字符并声称它是指针。操作系统尝试取消对指针的引用,但由于字符值不代表有效地址,因此操作失败。调用函数时,键入并强制转换整个字符串,而不仅仅是一个字符:

function GetStringTypeW(dwInfoType: DWORD; lpSrcStr: PWideChar; cchSrc: Integer; lpCharType: Pointer): BOOL;
GetStringTypeW(CT_CTYPE1, PWideChar(APassword), Length(APassword), PWordArray(aCharType))

你好,雷米。谢谢你的建议。不幸的是,即使以这种方式更改代码也不会改变结果:函数返回false,getlastEror返回1004Hello Remy。谢谢你的建议。不幸的是,即使以这种方式更改代码也不会改变结果:函数返回false,getlastEror返回1004