尝试使用以下示例设置SERVICE_TABLE_ENTRY时 Creating Windows service without Visual Studio 并使用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 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 }
};
}
但是编译器抱怨MY_SVC_NAME是错误的类型。
$ /usr/bin/i686-pc-mingw32-gcc -o /tmp/test ~/c/sample.c
sample.c: In function 'main':
sample.c:31:9: warning: initialization from incompatible pointer type
我尝试过分配变量并使用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 }
};
应该工作???
抱歉,另一个搜索显示了此示例代码 Windows Service C
我将代码更改为
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;
现在它编译时没有警告。
答案 0 :(得分:1)
此信息来自评论:
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_MAIN_FUNCTION
是函数返回void
并使用DWORD
和LPSTR
或LPWSTR
类型的两个参数的typedef。您的ServiceMain
函数会返回void
并接受类型为int
,char**
和char**
的三个参数。
更改ServiceMain
功能的定义,使其与LPSERVICE_MAIN_FUNCTION
兼容。
将ServiceMain
投射到LPSERVICE_MAIN_FUNCTION
会使编译器警告静音,但不会解决问题。这将导致您的函数被称为,就像它被正确声明一样,具有不可预测的结果(未定义的行为)。所有的演员都应该怀疑;如果您的编译器警告您类型不匹配,最好的解决方案通常是更改声明以使类型匹配,而不是强迫编译器假装它们没有问题。
(是否有{1 LPSTR
或LPWSTR
的typedef,具体取决于配置?)