1

我正在尝试向函数添加参数,并且我需要新参数是结构类型。

这是我要更改的功能,来自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_ttoT并且它编译得很好。

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

4

2 回答 2

4

似乎您不需要将结构类型的对象传递给函数(您只需要传递类型本身),因此正确的函数声明将是

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));

在这里您不一定需要显式指定类型,因为编译器可以从您传递的对象中推断出它。

于 2013-03-06T06:59:57.907 回答
2

您需要传递该类型的实际对象,而不是类型本身,作为参数:

method_t m;

prepare_patch_objc_methods(m, class_data->baseMethods, /* ... */);

编辑:如果不清楚:您不能将类型(例如method_t)作为普通参数传递——您只能将其作为模板参数传递。在函数模板的情况下,模板参数通常由编译器根据您为该参数传递的类型自动推导出来,因此:

template <class T>
void f(T x) {}

编译器将计算出,如果您将(例如)1作为参数传递,那么Tint用于此实例化。如果你通过1.0了,它会发现那Tdouble为了那个实例。

如果您真的想要(例如希望将值转换为 T 的类型,而不是选择 T 作为传递的任何类型),您可以为函数模板指定模板参数,就像您可以/为类模板所做的那样。例如,f<double>(1)将实例化f一个 double,即使您传递的值是一个 int。因此, int 在传递给函数之前将被提升为 double。

于 2013-03-06T06:07:44.820 回答