繁体   English   中英

E2010不兼容的类型:Delphi XE4中的“LPQUERY_SERVICE_CONFIGW”和“PQueryServiceConfigA”错误

[英]E2010 Incompatible types: 'LPQUERY_SERVICE_CONFIGW' and 'PQueryServiceConfigA' error in Delphi XE4

我在Delphi 7中的代码中有以下代码:

 var
    objServiceConfig: PQueryServiceConfigA;
    ...
    ...
    objServiceConfig:= AllocMem(anySize);
    ...
    ...
    QueryServiceConfig(hSCService, objServiceConfig, anySize, anySize2)
    .....
    .....

我收到错误: E2010 Incompatible types: 'LPQUERY_SERVICE_CONFIGW' and 'PQueryServiceConfigA'

在Delphi 7中一切正常但是将它迁移到Delphi XE4,我收到了这个错误。

当我更改上面的声明objServiceConfig: PQueryServiceConfigA; to objServiceConfig: LPQUERY_SERVICE_CONFIG; 有用。 它是对的还是我还有什么需要做的?

更新:

在Delphi XE4 WinSvc中,QueryServiceConfig声明如下

function QueryServiceConfig(hService: SC_HANDLE;
  lpServiceConfig: LPQUERY_SERVICE_CONFIG; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall;  

{$EXTERNALSYM QueryServiceConfigA}

function QueryServiceConfigA(hService: SC_HANDLE;
  lpServiceConfig: LPQUERY_SERVICE_CONFIGA; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall;

{$EXTERNALSYM QueryServiceConfigW}

function QueryServiceConfigW(hService: SC_HANDLE;
  lpServiceConfig: LPQUERY_SERVICE_CONFIGW; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall; 

在Delphi7,WinSvc中,QueryServiceConfig声明如下

function QueryServiceConfig(hService: SC_HANDLE;
  lpServiceConfig: PQueryServiceConfig; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall;

{$EXTERNALSYM QueryServiceConfigA}

function QueryServiceConfigA(hService: SC_HANDLE;
  lpServiceConfig: PQueryServiceConfigA; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall;

{$EXTERNALSYM QueryServiceConfigW}

function QueryServiceConfigW(hService: SC_HANDLE;
  lpServiceConfig: PQueryServiceConfigW; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall;

这意味着Delphi 7的第二个参数是PQueryServiceConfig / A / W类型,而Delphi XE4的类型是LPQUERY_SERVICE_CONFIG / A / W

你应该简单地使用

var
  objServiceConfig: PQueryServiceConfig;

这是宣布为PQueryServiceConfigA (ANSI版本)在Delphi 7和PQueryServiceConfigW在Delphi XE4(Unicode版本)。

编辑:

除非您打开了“Typed @ operator”编译器选项( {$T+} ),否则会产生编译器错误E2010 Incompatible types: 'LPQUERY_SERVICE_CONFIGW' and 'PQueryServiceConfigW' Delphi XE4中的E2010 Incompatible types: 'LPQUERY_SERVICE_CONFIGW' and 'PQueryServiceConfigW' 所以要么使用该选项,要么只是重新声明这样的函数:

function QueryServiceConfig(hService: SC_HANDLE; lpServiceConfig: PQueryServiceConfig; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall;
  external advapi32 name {$IFDEF UNICODE}'QueryServiceConfigW'{$ELSE}'QueryServiceConfigA'{$ENDIF};

这样它应该在Delphi 7和XE4中编译。

Delphi XE4支持Unicode,Delphi 7是ANSI版本。 所以QueryServiceConfig映射到QueryServiceConfigW上XE4,但QueryServiceConfigA上D7。

要解决问题(但请参阅下文),您应该将PQueryServiceConfigA替换为PQueryServiceConfig 现在, PQueryServiceConfig将映射到PQueryServiceConfigW以Unicode Delphi和PQueryServiceConfigA在ANSI德尔福。 这正是您需要的行为。

更重要的是,您应该确保已阅读并理解了MarcoCantù关于Delphi 2009中引入的Unicode更改的白皮书 如果你不这样做,看起来你没有,那么你的迁移将导致痛苦和痛苦。


实际上,它比那更复杂。 如果Delphi头文件翻译正确,上述内容都是准确的。 但事实并非如此。 它做错了。

QueryServiceConfig的声明是:

function QueryServiceConfig(hService: SC_HANDLE;
  lpServiceConfig: LPQUERY_SERVICE_CONFIG; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall;                   

但它应该是:

function QueryServiceConfig(hService: SC_HANDLE;
  lpServiceConfig: PQueryServiceConfig; cbBufSize: DWORD;
  var pcbBytesNeeded: DWORD): BOOL; stdcall;                   

因此,您需要将变量声明为LPQUERY_SERVICE_CONFIG类型以解决错误。

很抱歉花了这么长时间才到达底部。


似乎除此之外还有更多。 TOndrej正确地指出TYPEDADDRESS编译器指令的状态$T有影响。 默认设置为OFF 在这种情况下传递PQueryServiceConfigQueryServiceConfig导致编译器错误:

E2010 Incompatible types: 'LPQUERY_SERVICE_CONFIGW' and 'PQueryServiceConfigW'

如果您将设置切换为ON (我强烈建议),则编译成功。

为了理解原因,我们需要了解如何声明这些类型和函数。 我已经删除了ANSI声明以保持简单说明:

type
  LPQUERY_SERVICE_CONFIGW = ^QUERY_SERVICE_CONFIGW;
  LPQUERY_SERVICE_CONFIG = LPQUERY_SERVICE_CONFIGW;
  QUERY_SERVICE_CONFIGW = record
    ...
  end;
  QUERY_SERVICE_CONFIG = QUERY_SERVICE_CONFIGW;
  _QUERY_SERVICE_CONFIGW = QUERY_SERVICE_CONFIGW;
  PQueryServiceConfigW = ^TQueryServiceConfigW;
  PQueryServiceConfig = PQueryServiceConfigW;
  TQueryServiceConfigW = QUERY_SERVICE_CONFIGW;
  TQueryServiceConfig = TQueryServiceConfigW;

function QueryServiceConfig(... lpServiceConfig: LPQUERY_SERVICE_CONFIG ...

现在,在T-状态,文档说:

在{$ T-}状态中,除指针之外的不同指针类型是不兼容的(即使它们是指向相同类型的指针)。

这解释了编译错误。 因为LPQUERY_SERVICE_CONFIGPQueryServiceConfig不同。

现在,类型可以通过这种方式声明:

type
  QUERY_SERVICE_CONFIGW = record
  end;
  QUERY_SERVICE_CONFIG = QUERY_SERVICE_CONFIGW;
  _QUERY_SERVICE_CONFIGW = QUERY_SERVICE_CONFIGW;
  TQueryServiceConfigW = QUERY_SERVICE_CONFIGW;
  TQueryServiceConfig = TQueryServiceConfigW;

  LPQUERY_SERVICE_CONFIGW = ^QUERY_SERVICE_CONFIGW;
  LPQUERY_SERVICE_CONFIG = LPQUERY_SERVICE_CONFIGW;
  PQueryServiceConfigW = LPQUERY_SERVICE_CONFIGW;
  PQueryServiceConfig = PQueryServiceConfigW;

然后你可以将四种指针类型中的任何一种传递给函数,因为它们实际上是所有相同类型的别名。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM