函数指针强制转换为具有继承 C 结构的函数

Function pointer cast on function with inherited C structure

如果示例函数转换和调用在 C 中有效,我正在寻找答案(如果没有任何示例,如何获得类似的行为会很好)。

示例:

#include <stdio.h>
#include <stdint.h>

typedef struct {
    uint32_t a;
} parent_t;

typedef struct {
    parent_t parent;
    uint32_t b;
} child_t;


typedef void (*funct_ptr_t)(parent_t* pParent, uint32_t x);

void test_function(child_t* pChild, uint32_t x);

int main()
{ 
    funct_ptr_t func = (funct_ptr_t)test_function;
    funct(NULL, 0U);

    return 0;
}

void test_function(child_t* pChild, uint32_t x) {
    // do something
}

@编辑 由于上面转为无效,我还想问一下第二种方法

typedef void (*funct_ptr_t)(void* pChild, uint32_t x);

void test_function(child_t* pChild, uint32_t x);

int main()
{ 
    funct_ptr_t func = (funct_ptr_t)test_function;
    child_t child;
    func(&child, 0U);

    return 0;
}

void test_function(child_t* pChild, uint32_t x) {
    // do something
}

这是无效的。

只能通过兼容的函数指针类型调用函数。为了使两个函数指针类型兼容,相应的参数必须具有兼容的类型并且 return 类型必须兼容。

test_function 的类型为 void (*)(child_t*, uint32_t ),但正在通过类型为 void (*)(parent_t*, uint32_t ) 的函数指针调用。这意味着该函数是通过不兼容的类型调用的,这样做会触发 undefined behavior.

如果您尝试为第一个参数接受指向不同类型的指针,处理此问题的最简单方法是将函数和函数指针的第一个参数的类型更改为 void * , 然后在函数内部进行必要的转换。

另一种选择是将第一个参数的类型更改为 test_functionparent_t * 并在函数内部执行强制转换。这将起作用,因为指向结构的指针可以转换为指向其第一个成员的指针,因此您可以这样做:

void test_function(parent_t* pChild, uint32_t x);

int main()
{ 
    funct_ptr_t func = (funct_ptr_t)test_function;
    child_t c;
    funct((parent_t *)&c, 0U);

    return 0;
}

void test_function(parent_t* p, uint32_t x) {
    child_t *p_Child = (p_Child *)p;
    // do something
}