我知道这个宏的大部分内容在做什么。但对于三重'###'。我知道'##'会做什么。它只是将单词/数字加在一起。
但到目前为止,我从未见过三次'###'。
#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是钩子函数。我是对的?
答案 0 :(得分:1)
###
并不特别,只有##
后跟#
。 ##
用于连接,#
用于字符串化,因此L ## # x
可以 1 成为L"x"
。
对于HOOKDEF
,New_...
不会在那里使用。据我所知,它只是声明Old_...
并定义New_...
。我怀疑代码中有一些额外的部分,但是您的问题缺少,这使得对getaddrinfo
的所有调用实际上调用New_getaddrinfo
而调用者没有意识到这一点。
实际上,仔细观察,这似乎是您的HOOK
宏的用途,它也以同样的方式将New_
添加到函数名称,并允许其用户查看新函数。
1 严格地说,除非编译器在#
之前处理##
,否则不需要工作,但是你的编译器会做的是这段代码期望它。