我正在尝试向函数添加参数,我需要将新参数作为结构类型。
以下是我要更改的功能,来自dyld_decache.cpp
void prepare_patch_objc_methods(uint32_t method_vmaddr, uint32_t override_vmaddr);
我这样改了:
template <typename T>
void prepare_patch_objc_methods(typename T::type, uint32_t list_vmaddr, uint32_t override_vmaddr);
在prepare_patch_objc_methods
的实施过程中,我将所有出现的method_t
更改为T
,并且编译得很好。
method_t
结构的定义如下:
struct method_t {
uint32_t name;
uint32_t types;
uint32_t imp;
};
现在,如何在调用此函数时传递结构类型?
我试图这样做
this->prepare_patch_objc_methods(method_t, class_data->baseMethods, class_obj->data + offsetof(class_ro_t, baseMethods));
但是我收到以下错误:'method_t' does not refer to a value
答案 0 :(得分:4)
看起来你不需要将你的struct类型的对象传递给函数(你只需要传递一个类型本身),所以正确的函数声明将是
template <typename T>
void prepare_patch_objc_methods(uint32_t list_vmaddr, uint32_t override_vmaddr);
现在将结构类型传递给你称之为函数的函数
this->prepare_patch_objc_methods<method_t>(class_data->baseMethods, class_obj->data + offsetof(class_ro_t, baseMethods));
如果你确实需要传递参数类型的对象,你可以这样做
template <typename T>
void prepare_patch_objc_methods(const T &object, uint32_t list_vmaddr, uint32_t override_vmaddr);
然后你这样称呼它
method_t obj;
this->prepare_patch_objc_methods<method_t>(obj, class_data->baseMethods, class_obj->data + offsetof(class_ro_t, baseMethods));
或者只是喜欢这个
this->prepare_patch_objc_methods(obj, class_data->baseMethods, class_obj->data + offsetof(class_ro_t, baseMethods));
在这里,您不一定需要明确指定类型,因为编译器可以从您传递的对象中推断出它。
答案 1 :(得分:2)
您需要传递该类型的实际对象,而不是类型本身,作为参数:
method_t m;
prepare_patch_objc_methods(m, class_data->baseMethods, /* ... */);
编辑:如果不清楚:您不能将类型(例如method_t
)作为普通参数传递 - 您只能将其作为模板参数传递。对于函数模板,模板参数通常由编译器根据您为该参数传递的类型自动推导出来,因此给出:
template <class T>
void f(T x) {}
编译器会发现,如果您传递(例如)1
作为参数,则T
将为此实例化int
。如果您改为通过1.0
,则会发现该T
double
为{}}。
如果你真的想(比如想要将值转换为T的类型,而不是选择T作为传递的任何类型),你可以为函数模板指定一个模板参数,就像你可以为类做的那样模板。例如,f<double>(1)
将为double实例化f
,即使您传递的值是int。因此,在传递给函数之前,int将被提升为double。