函数指针和DLL加载顺序

时间:2011-10-12 07:43:58

标签: c++ windows winapi

我正在使用函数指针和LoadLibrary。以下是我的代码。当我在EvtExportLog调用后添加_EvtSubscribe时,它开始破坏_EvtSubscribe值,如果我在下面的代码中添加之前一切正常,现在当我添加另一个函数指针时我正面临同样的问题,任何人都知道这里可能存在什么问题。

     HMODULE module = LoadLibrary(L"wevtapi.dll");
    _EvtExportLog             = (BOOL (WINAPI * )(EVT_HANDLE ,LPCWSTR ,LPCWSTR ,LPCWSTR ,DWORD ))GetProcAddress(module, "EvtExportLog");
    _EvtClearLog              = (BOOL (WINAPI * )(EVT_HANDLE ,LPCWSTR,LPCWSTR,DWORD))GetProcAddress(module, "EvtClearLog");
    _EvtOpenLog               = (EVT_HANDLE  (WINAPI *)(EVT_HANDLE ,LPCWSTR ,DWORD ))GetProcAddress(module, "EvtOpenLog");
    _EvtGetLogInfo            = (BOOL (WINAPI * )( EVT_HANDLE, EVT_LOG_PROPERTY_ID, DWORD, PEVT_VARIANT ,PDWORD))GetProcAddress(module, "EvtGetLogInfo");
    _EvtQuery                 = (EVT_HANDLE (WINAPI * )(EVT_HANDLE,LPCWSTR ,LPCWSTR ,DWORD))GetProcAddress(module, "EvtQuery");
    _EvtNext                  = (BOOL (WINAPI * )(EVT_HANDLE ,DWORD,EVT_HANDLE*,DWORD,DWORD,PDWORD))GetProcAddress(module, "EvtNext");
    _EvtClose                 = (BOOL (WINAPI *)(EVT_HANDLE))GetProcAddress(module, "EvtClose");
    _EvtCreateRenderContext   = (EVT_HANDLE (WINAPI *)(DWORD, LPCWSTR *, DWORD))GetProcAddress(module, "EvtCreateRenderContext");
    _EvtFormatMessage         = (BOOL (WINAPI *)(EVT_HANDLE, EVT_HANDLE, DWORD, DWORD, PEVT_VARIANT, DWORD, DWORD, LPWSTR, PDWORD))GetProcAddress(module, "EvtFormatMessage");
    _EvtOpenPublisherMetadata = (EVT_HANDLE (WINAPI *)(EVT_HANDLE, LPCWSTR, LPCWSTR, LCID, DWORD))GetProcAddress(module, "EvtOpenPublisherMetadata");
    _EvtRender                = (BOOL (WINAPI *)(EVT_HANDLE, EVT_HANDLE, DWORD, DWORD, PVOID, PDWORD, PDWORD))GetProcAddress(module, "EvtRender");
    _EvtSubscribe             = (EVT_HANDLE (WINAPI *)(EVT_HANDLE, HANDLE, LPCWSTR, LPCWSTR, EVT_HANDLE, PVOID, EVT_SUBSCRIBE_CALLBACK, DWORD))GetProcAddress(module, "EvtSubscribe");

1 个答案:

答案 0 :(得分:3)

这与DLL加载顺序无关,你在其他地方捣毁堆栈,而且只是_EvtSubscribe是受害者,这取决于你如何在堆栈上订购对象。删除堆栈的最简单方法是,如果您使用错误的签名调用函数,可能是通过手动转录它们而不是仅使用静态链接和标头。