我知道这个宏的大部分功能在做什么。但是对于三重'###'s。我知道双'##'是做什么的。它只是将单词/数字连接在一起。

但是到目前为止,我还从未见过三重'###'在一起。

#define HOOK(library, funcname) {L###library, #funcname, NULL, \
&New_##funcname, (void **) &Old_##funcname}

我也想知道这个宏在做什么。
#define HOOKDEF( return_value, calling_convention, apiname, ... ) \
return_value ( calling_convention *Old_##apiname )( __VA_ARGS__ ); \
return_value calling_convention New_##apiname( __VA_ARGS__ )

我知道宏是一个函数指针宏。但是我对';'之后的部分不了解
return_value calling_convention New_##apiname( __VA_ARGS__ )

我知道它将加入New_apiname。。但是在任何代码中我都看不到单词New_。

HOOKDEF的示例:
HOOKDEF(int, WSAAPI, getaddrinfo,
_In_opt_  PCSTR pNodeName,
_In_opt_  PCSTR pServiceName,
_In_opt_  const ADDRINFOA *pHints,
_Out_     PADDRINFOA *ppResult
) {
IS_SUCCESS_ZERO();

BOOL ret = Old_getaddrinfo(pNodeName, pServiceName, pHints, ppResult);
LOQ("ss", "NodeName", pNodeName, "ServiceName", pServiceName);
return ret;
}

我不明白的是New_apifunc()应该在哪里发挥作用?

该宏是否使HOOKDEF自动成为New_apifunc()?

因为通常您会钩住这样的东西:
#define HOOK( func, addy )  o##func = ( func##_t )DetourFunction( (PBYTE)addy, (PBYTE)hk##func )

// --- HOOK DRAW INDEXED PRIMITIVE ---
HRESULT WINAPI hkDrawIndexedPrimitive( LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount )
{
    __asm nop

    // Do whatever...

    return oDrawIndexedPrimitive( pDevice, PrimType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount );

}// END HOOK DRAW INDEXED PRIMITIVE

在此示例中,您可以清楚地在宏中看到新的hkfunc()和旧的ofunc()。

但是我认为HOOKDEF是挂钩函数。我是对的吗?

最佳答案

###没什么特别的,只是##后跟###用于连接,#用于字符串化,因此L ## # x can1成为L"x"

至于HOOKDEF,在那里不使用New_...。据我所知,它只是声明Old_...并定义New_...。我怀疑代码中还有一些多余的部分,这是您的问题所缺少的,这使得对getaddrinfo的所有调用实际上都在调用者未意识到的情况下,调用了New_getaddrinfo

实际上,更仔细地看,这似乎是HOOK宏的用途,它也以相同的方式将New_前缀为一个函数名称,并允许其用户查看新函数。

1严格来说,除非编译器在#之前处理##,否则不需要工作,但是您的编译器将执行此代码作者期望的操作。

关于c++ - C宏使用 '##'和 '###'也是指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21982525/

10-13 07:02