我在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;
更改为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
答案 0 :(得分:5)
您应该只使用
var
objServiceConfig: PQueryServiceConfig;
在Delphi 7中声明为PQueryServiceConfigA
(ANSI版本),在Delphi XE4中声明为PQueryServiceConfigW
(Unicode版本)。
修改强>
除非您打开了“Typed @ operator”编译器选项({$T+}
),否则在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中编译。
答案 1 :(得分:3)
Delphi XE4支持Unicode,Delphi 7是ANSI版本。因此,QueryServiceConfig
会在XE4上映射到QueryServiceConfigW
,但在D7上映射到QueryServiceConfigA
。
要解决问题(但请参阅下文),您应将PQueryServiceConfigA
替换为PQueryServiceConfig
。现在,PQueryServiceConfig
将映射到Unicode Delphi中的PQueryServiceConfigW
和ANSI Delphi中的PQueryServiceConfigA
。这恰恰就是你需要的行为。
更重要的是,您应确保已阅读并理解Marco Cantù's whitepaper on the Unicode changes introduced in Delphi 2009。如果你不这样做,看起来你没有,那么你的迁移将导致痛苦和痛苦。
实际上,它比那更复杂。如果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
。在这种情况下,将PQueryServiceConfig
传递给QueryServiceConfig
会导致编译器错误:
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_CONFIG
与PQueryServiceConfig
不同。
现在,这些类型可以通过这种方式声明:
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;
然后你可以将四种指针类型中的任何一种传递给函数,因为它们实际上是所有相同类型的别名。