首页
社区
课程
招聘
[分享]变参模板封装调用约定
发表于: 2019-10-23 15:20 9957

[分享]变参模板封装调用约定

2019-10-23 15:20
9957

这样我们就可以统一的管理、调用call啦,比如异常捕捉、日志、统计、行为序列

typedef void(__stdcall *FunctionDefine)(void* param);
FunctionDefine function = (FunctionDefine)0xAABBCCDD;
function(param);
void function(void* param)
{
__asm{
push param
mov eax,0xAABBCCDD
call eax
}
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 4
支持
分享
最新回复 (12)
雪    币: 1176
活跃值: (1269)
能力值: ( LV12,RANK:380 )
在线值:
发帖
回帖
粉丝
2
思路不错 还可以再优雅点...
2019-10-23 20:27
0
雪    币: 3623
活跃值: (656)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
3
请Tennn老师发言
2019-10-24 09:16
0
雪    币: 405
活跃值: (1096)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
4
调用约定也写成模版参数?
2019-10-24 11:29
0
雪    币: 3623
活跃值: (656)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
5
看雪的引用现在又没用了?我是回复来着,结果没生效
2019-10-24 13:13
0
雪    币: 3623
活跃值: (656)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
6
大佬们再补充点啊,
2019-10-24 17:05
0
雪    币: 405
活跃值: (1096)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
7
mb_ldtiaylu 大佬们再补充点啊,
BlackBone里面的RemoteCall有类似的变参模板,但是在申明的时候还是得提供完整的函数类型,可以细细品一下,这里这种写法可以参数自动推导,省事一丢丢,具体看自己的使用场景去改造改造
2019-10-24 19:35
0
雪    币: 1042
活跃值: (550)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
一般我是直接asm.学习了。
2019-10-25 00:37
0
雪    币: 3623
活跃值: (656)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
9
 
最后于 2019-10-25 16:57 被mb_ldtiaylu编辑 ,原因:
2019-10-25 16:56
0
雪    币: 4506
活跃值: (4483)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
vs2010 好像不支持 最低版本 2015 ???
2020-8-7 11:27
0
雪    币: 576
活跃值: (2035)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
翻出来了就mark一下 
2022-3-13 15:11
0
雪    币: 1935
活跃值: (4180)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
mark
2022-3-17 09:31
0
雪    币: 6124
活跃值: (4721)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
13
#pragma once

#include <type_traits>

namespace base {

	namespace call_ {
		template <class OutputClass, class InputClass>
		struct same_size {
			static const bool value = 
				(!std::is_reference_v<InputClass> && sizeof(OutputClass) == sizeof(InputClass))
				|| (std::is_reference_v<InputClass> && sizeof(OutputClass) == sizeof(std::add_pointer_t<InputClass>));
		};

		template <class OutputClass, class InputClass>
		union cast_union
		{
			OutputClass out;
			InputClass in;
		};

		template <class Argument>
		inline uintptr_t cast(const Argument input, std::enable_if_t<std::is_function_v<std::remove_reference_t<Argument>>, void>* = 0)
		{
			cast_union<uintptr_t, Argument> u;
			static_assert(std::is_trivially_copyable_v<Argument>, "Argument is not a pod.");
			static_assert((sizeof(Argument) == sizeof(u)) && (sizeof(Argument) == sizeof(uintptr_t)), "Argument and uintptr_t are not the same size.");
			u.in = input;
			return u.out;
		}

		template <class Argument>
		inline uintptr_t cast(const Argument input, std::enable_if_t<!std::is_function_v<std::remove_reference_t<Argument>> && same_size<uintptr_t, Argument>::value, void>* = 0)
		{
			cast_union<uintptr_t, Argument> u{};
			static_assert(std::is_trivially_copyable_v<Argument>, "Argument is not a pod.");
			u.in = input;
			return u.out;
		}

		template <class Argument>
		inline uintptr_t cast(const Argument input, std::enable_if_t<!std::is_function_v<std::remove_reference_t<Argument>> && !same_size<uintptr_t, Argument>::value, void>* = 0)
		{
			static_assert(std::is_trivially_copyable_v<Argument>, "Argument is not a pod.");
			static_assert(sizeof(Argument) < sizeof(uintptr_t), "Argument can not be converted to uintptr_t.");
			return static_cast<uintptr_t>(input);
		}

		template <typename Arg>
		struct cast_type {
			typedef uintptr_t type;
		};
	}

	template <typename R, typename F, typename ... Args>
	inline R std_call(F f, Args ... args)
	{
		return (reinterpret_cast<R(__stdcall *)(typename call_::cast_type<Args>::type ... args)>(f))(call_::cast(args)...);
	}

	template <typename R, typename F, typename ... Args>
	inline R fast_call(F f, Args ... args)
	{
		return (reinterpret_cast<R(__fastcall *)(typename call_::cast_type<Args>::type ... args)>(f))(call_::cast(args)...);
	}

	template <typename R, typename F, typename ... Args>
	inline R c_call(F f, Args ... args)
	{
		return (reinterpret_cast<R(__cdecl *)(typename call_::cast_type<Args>::type ... args)>(f))(call_::cast(args)...);
	}

	template <typename R, typename F, typename This, typename ... Args>
	inline R this_call(F f, This t, Args ... args)
	{
		return (reinterpret_cast<R(__fastcall *)(typename call_::cast_type<This>::type, void*, typename call_::cast_type<Args>::type ... args)>(f))(call_::cast(t), 0, call_::cast(args)...);
	}
}

P.S: 需要C++20

最后于 2022-6-5 00:24 被黑洛编辑 ,原因:
2022-6-4 23:25
2
游客
登录 | 注册 方可回帖
返回
//