简体   繁体   中英

How to pass a struct type as a parameter to a function?

I'm trying to add a parameter to a function and I need the new parameter to be a struct type.

Here is the function I want to change, from dyld_decache.cpp

void prepare_patch_objc_methods(uint32_t method_vmaddr, uint32_t override_vmaddr);

I changed it like this:

template <typename T>
void prepare_patch_objc_methods(typename T::type, uint32_t list_vmaddr, uint32_t override_vmaddr);

Inside the implementation of prepare_patch_objc_methods , I changed all occurrences of method_t to T and it compiles fine.

The method_t struct is defined like this:

struct method_t {
    uint32_t name;
    uint32_t types;
    uint32_t imp;
};

Now, how do I pass a struct type when calling this function?

I tried to do this

this->prepare_patch_objc_methods(method_t, class_data->baseMethods, class_obj->data + offsetof(class_ro_t, baseMethods));

but I get the following error: 'method_t' does not refer to a value

It seems that you dont need to pass an object of your struct type into the function (you just need to pass a type itself), so the correct function declaration would be

template <typename T>
void prepare_patch_objc_methods(uint32_t list_vmaddr, uint32_t override_vmaddr);

Now to pass a struct type to a function you call it like this

this->prepare_patch_objc_methods<method_t>(class_data->baseMethods, class_obj->data + offsetof(class_ro_t, baseMethods));

In case you actually need to pass an object of a parameter type, you do something like this

template <typename T>
    void prepare_patch_objc_methods(const T &object, uint32_t list_vmaddr, uint32_t override_vmaddr);

Then you call it like this

method_t obj;
this->prepare_patch_objc_methods<method_t>(obj, class_data->baseMethods, class_obj->data + offsetof(class_ro_t, baseMethods));

or simply like this

this->prepare_patch_objc_methods(obj, class_data->baseMethods, class_obj->data + offsetof(class_ro_t, baseMethods));

Here you dont necessarily need to specify the type explicitly because the compiler can deduce it from the object you are passing.

You need to pass an actual object of that type, not the type itself, as the parameter:

method_t m;

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

Edit: in case this isn't clear: you can't pass a type (such as method_t ) as a normal parameter -- you can only pass it as a template parameter. In the case of a function template, the template parameters are typically deduced automatically by the compiler from the type you pass for that parameter, so given:

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

The compiler will figure out that if you pass (for example) 1 as the parameter, then T will be int for this instantiation. If you pass 1.0 instead, it'll figure out that T is double for that intantiation.

If you really want to (such as wanting value converted to the type of T, instead of T being chosen as whatever type is passed) you can specify a template parameter for a function template about like you can/do for a class template. For example, f<double>(1) will instantiate f for a double, even though the value you've passed is an int. Therefore, the int will be promoted to double before being passed to the function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM