使用winsvc.h中的SERVICE_TABLE_条目避免编译器警告的正确类型转换是什么
尝试使用以下示例设置服务\u表\u项时: 在Fedora 14上使用mingw32交叉编译器进行编译时,我收到一条编译器警告 我能做的最短样品是使用winsvc.h中的SERVICE_TABLE_条目避免编译器警告的正确类型转换是什么,c,windows-services,C,Windows Services,尝试使用以下示例设置服务\u表\u项时: 在Fedora 14上使用mingw32交叉编译器进行编译时,我收到一条编译器警告 我能做的最短样品是 #include <stdio.h> #include <windows.h> #include <winsvc.h> #define MY_SVC_NAME "My Service" int cont_running = 1; DWORD WINAPI ServiceHandlerProc(DWORD Con
#include <stdio.h>
#include <windows.h>
#include <winsvc.h>
#define MY_SVC_NAME "My Service"
int cont_running = 1;
DWORD WINAPI ServiceHandlerProc(DWORD ControlCode, DWORD a, void *b, void *c)
{
switch (ControlCode)
{
case SERVICE_CONTROL_STOP : ;
cont_running = 0;
}
return 0;
}
void WINAPI ServiceMain(int argc, char *argv[], char *envp[])
{
int hServiceStatus;
hServiceStatus = RegisterServiceCtrlHandlerEx(MY_SVC_NAME, ServiceHandlerProc, 0);
}
int main(int argc, char *argv[], char *envp[])
{
SERVICE_TABLE_ENTRY ServiceStartTable[] =
{
{ MY_SVC_NAME, ServiceMain },
{ 0, 0 }
};
}
我尝试分配一个变量并使用LPSTR LPWSTR char*和char[]类型,还尝试在花括号内强制转换该类型,但它不起作用
查看/usr/i686-pc-mingw32/sys root/mingw/include/winsvc.h,我发现它的定义如下
typedef struct _SERVICE_TABLE_ENTRYA {
LPSTR lpServiceName;
LPSERVICE_MAIN_FUNCTIONA lpServiceProc;
} SERVICE_TABLE_ENTRYA,*LPSERVICE_TABLE_ENTRYA;
typedef struct _SERVICE_TABLE_ENTRYW {
LPWSTR lpServiceName;
LPSERVICE_MAIN_FUNCTIONW lpServiceProc;
} SERVICE_TABLE_ENTRYW,*LPSERVICE_TABLE_ENTRYW;
...
typedef SERVICE_TABLE_ENTRYW SERVICE_TABLE_ENTRY,*LPSERVICE_TABLE_ENTRY;
...
typedef SERVICE_TABLE_ENTRYA SERVICE_TABLE_ENTRY,*LPSERVICE_TABLE_ENTRY;
因此,使用
LPSTR my_svc=MY_SVC_NAME;
SERVICE_TABLE_ENTRY ServiceStartTable[] =
{
{ my_svc, ServiceMain },
{ 0, 0 }
};
应该工作吗
抱歉,另一次搜索在上显示了此示例代码
我把代码改成了
SERVICE_TABLE_ENTRY ServiceStartTable[2];
ServiceStartTable[0].lpServiceName = MY_SVC_NAME;
ServiceStartTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceStartTable[1].lpServiceName = NULL;
ServiceStartTable[1].lpServiceProc = NULL;
现在它编译时没有警告。此信息来自评论:
typedef void (WINAPI LPSERVICE_MAIN_FUNCTIONA)(DWORD,LPSTR);
typedef void (WINAPI LPSERVICE_MAIN_FUNCTIONW)(DWORD,LPWSTR);
typedef LPSERVICE_MAIN_FUNCTIONA LPSERVICE_MAIN_FUNCTION;
typedef LPSERVICE_MAIN_FUNCTIONW LPSERVICE_MAIN_FUNCTION;
(大概后两个TypeDef中只有一个处于活动状态。)
LPSERVICE\u MAIN\u函数
是一个typedef,用于返回void
并接受两个类型为DWORD
和LPSTR
或LPWSTR
的参数的函数。您的ServiceMain
函数返回void
,并接受三种类型的参数int
、char**
和char**
更改ServiceMain
函数的定义,使其与LPSERVICE\u MAIN\u函数
兼容
将ServiceMain
强制转换为LPSERVICE\u MAIN\u函数将使编译器警告静音,但不会解决问题。它将导致调用函数,就好像它被正确声明一样,结果是不可预测的(未定义的行为)。所有演员都应该以怀疑的眼光看待;如果编译器警告您类型不匹配,最好的解决方案通常是更改声明以使类型匹配,而不是强迫编译器假装它们正常
(是否存在LPSTR
或LPWSTR
的类型定义,具体取决于配置?如何定义LPSERVICE\u MAIN\u功能
?我有一种强烈的预感,它需要返回int
,而不是void
。尝试更改ServiceMain
函数以返回int
,并删除强制转换。@KeithThompson谢谢,但typedef确实指定了void。`typedef void(WINAPI LPSERVICE_MAIN_function)(DWORD,LPSTR);typedef void(WINAPI LPSERVICE_MAIN_FUNCTIONW)(DWORD,LPWSTR);类型定义LPSERVICE_MAIN_功能LPSERVICE_MAIN_功能;typedef LPSERVICE_MAIN_函数w LPSERVICE_MAIN_函数`你在评论中漏掉了一个尾声;您仍然有时间编辑它。是的-我编辑了几次,甚至删除了\n,但我想它太长或太多其他字符,回勾无法正常工作。您只需在开始回勾之后和结束回勾之前删除空格(注释中忽略换行):typedef void(WINAPI LPSERVICE\u MAIN\u函数)(DWORD,LPSTR);typedef void(WINAPI LPSERVICE_MAIN_FUNCTION w)(DWORD,LPWSTR);typedef LPSERVICE_MAIN_FUNCTION LPSERVICE_MAIN_FUNCTION;typedef LPSERVICE_MAIN_FUNCTION w LPSERVICE_MAIN_FUNCTION;
typedef void (WINAPI LPSERVICE_MAIN_FUNCTIONA)(DWORD,LPSTR);
typedef void (WINAPI LPSERVICE_MAIN_FUNCTIONW)(DWORD,LPWSTR);
typedef LPSERVICE_MAIN_FUNCTIONA LPSERVICE_MAIN_FUNCTION;
typedef LPSERVICE_MAIN_FUNCTIONW LPSERVICE_MAIN_FUNCTION;