首页 > 解决方案 > Windows C++:如何定义 WINAPI 类型的回调成员函数?

问题描述

我编写了一个程序,它从netsh 跟踪实用程序生成的 ETL 文件中读取 Windows ETW 数据。我正在使用标准的 Windows 事件跟踪库来执行此操作,这需要我进行一些初始设置工作,注册一个回调函数(使用 PEVENT_RECORD_CALLBACK),然后调用一个名为 ProcessTrace(...) 的函数。

这作为静态函数工作得很好,但由于一些原因,我需要将代码移动到 netsh 阅读器类 (NetshReader) 中。我在定义回调函数时遇到问题。如果我运行下面的示例代码,我会在调用 ProcessTrace(...) 函数后立即获得访问冲突。

我怀疑问题在于回调函数必须是静态的,但我想我会用更聪明的头脑来检查。

我可以将 ProcessTrace(...) 回调定义为成员函数吗?

在此先感谢...保罗

#pragma once

#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <evntrace.h>
#include <tdh.h>

#pragma comment(lib, "tdh.lib")

using namespace std;

class NetshReader
{
public:
    void processNetshTrace();
    void WINAPI processFirstPass(PEVENT_RECORD pEvent);
};

void WINAPI NetshReader::processFirstPass(PEVENT_RECORD pEvent)
{
    std::wcout << "In callback function" << std::endl;
}

void NetshReader::processNetshTrace()
{
    std::wstring stemp = L"C:\\traces\\a7-netsh.etl";

    EVENT_TRACE_LOGFILE trace;
    TRACE_LOGFILE_HEADER* pHeader = &trace.LogfileHeader;
    TRACEHANDLE g_hTrace = 0;  // Handle to the trace file that you opened.

    ZeroMemory(&trace, sizeof(EVENT_TRACE_LOGFILE));

    trace.LogFileName = &stemp[0];

    trace.EventRecordCallback = (PEVENT_RECORD_CALLBACK)(&NetshReader::processFirstPass, this);

    trace.ProcessTraceMode = PROCESS_TRACE_MODE_EVENT_RECORD;

    g_hTrace = OpenTrace(&trace);

    if (INVALID_PROCESSTRACE_HANDLE == g_hTrace)
        std::wcout << "OpenTrace failed" << std::endl;

    ProcessTrace(&g_hTrace, 1, 0, 0); // <<=== Access violation here because tries to
                                      //       callback to NetshReader object address
                                      //       (i.e. "this")
}

int wmain(int argc, wchar_t** argv)
{
    NetshReader* rdr = new NetshReader();
    rdr->processNetshTrace();

    return(0);
}

我用来测试的 ETL 文件在这里:https ://a7pub.s3-eu-west-1.amazonaws.com/a7-netsh.etl

标签: c++callbacketw

解决方案


推荐阅读