如何为具有不同参数的函数声明一系列函数指针?

发布于 2025-01-22 19:44:57 字数 185 浏览 0 评论 0原文

我正在为项目编写一些测试,并且功能具有相同的返回类型,但参数数量不同。我想使用一系列功能指针来调用这些测试功能。如何为此类功能声明一系列功能指针?

这些功能被声明为:

bool test1();
bool test2(char const *string, uint32_t length);

I am writing some tests for my project, and the functions have the same return type but a different number of parameters. I want to use an array of function pointers to call these test functions. How to declare an array of function pointers for such functions?

The functions are declared as:

bool test1();
bool test2(char const *string, uint32_t length);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

漫雪独思 2025-01-29 19:44:57

考虑一下功能指针不是魔术,他们仍然必须遵守ABI调用惯例,这意味着具有一定签名的函数与具有不同签名的函数本质上不同。

使用功能指针更多的是使用动态方法,而不是实现多态性。编辑:这不是多态性。

但是,您可以通过更换每个测试功能来接受void*,然后在结构中编码您的参数来完成一些问题。

// Declare the test functions

//bool test1();
bool test1(void* struct_address)
{
    // struct address unused.
}

// Parameters for test2
struct test2{
    char const* string;
    uint32_t*   length;
}

//bool test2(char const *string, uint32_t length);
bool test2(void* struct_address)
{
    struct test2 test2_s = *(struct test2*)(struct_address);

    // Work with test2_s
}

// Declare the function pointer 
bool (*test_ptr)(void *);

// call test1
test_ptr = test1; test_ptr((void*)NULL);

// call test2
struct test2 test2_s = {param1,param2};
test_ptr = test2; test_ptr((void*)&test2_s);

请小心,因为如果您传递了错误的结构类型,则会获得内存泄漏和细分错误。但是,由于这是一个测试环境,因此可以缓解这一点。

Consider that function pointers are not magic tricks, they still have to abide to the ABI calling convention, meaning that a function with a certain signature is intrinsically different from a function with a different signature.

Using a function pointer is more of a way to have dynamic methods, than to achieve polymorphism. EDIT: This is not polymorphism.

However, you can accomplish somewhat you ask by replacing each of the test functions to accept a void* and then code your parameters in a struct.

// Declare the test functions

//bool test1();
bool test1(void* struct_address)
{
    // struct address unused.
}

// Parameters for test2
struct test2{
    char const* string;
    uint32_t*   length;
}

//bool test2(char const *string, uint32_t length);
bool test2(void* struct_address)
{
    struct test2 test2_s = *(struct test2*)(struct_address);

    // Work with test2_s
}

// Declare the function pointer 
bool (*test_ptr)(void *);

// call test1
test_ptr = test1; test_ptr((void*)NULL);

// call test2
struct test2 test2_s = {param1,param2};
test_ptr = test2; test_ptr((void*)&test2_s);

Be careful because if you pass the wrong struct type you will get memory leaks and segmentation errors. Since this is a test environment, however, this can be mitigated.

很酷又爱笑 2025-01-29 19:44:57

在C中,函数声明中的一个空参数列表并不意味着该函数采用 no参数;相反,这意味着它需要一个未指定的参数。。 1

因此,至少从语法上讲,您可以指定一系列功能指针,每个函数指针都有一个未指定的参数数量(但是固定的返回类型),类似:bool(*fnptrarray [100])();。然后,您可以将具有不同参数类型和数字的函数的地址分配给此类数组的不同元素。但是,就不会有编译时检查这些函数是否正确调用,或者对给定参数类型的任何隐式转换为“正确”式形式。

下面的代码说明了这一点(但请注意, 我不建议使用这样的代码 ,因为通过不正确参数可能会导致固有的危险):

#include <stdio.h>
#include <stdbool.h>

bool Foo(int a) {
    printf("Foo: %d ...\n", a);
    return a % 2;
}

bool Bar(double x, double y) {
    printf("Bar: %5.3lf %5.3lf...\n", x, y);
    return x < y;
}

int main()
{
    bool (*FnPtrArray[100])();

    // So we can't tell at compile time which elements point where ...
    printf("Enter a number: ");
    int n = 42;
    scanf("%d", &n);
    if (n % 2) {
        FnPtrArray[0] = Foo;
        FnPtrArray[1] = Bar;
    }
    else {
        FnPtrArray[1] = Foo;
        FnPtrArray[0] = Bar;
    }

    // Notes assuming given "n" is odd ...
    printf("%d\n\n", FnPtrArray[0](3));         // Works
    printf("%d\n\n", FnPtrArray[0](3.0));       // Wrong argument type
    printf("%d\n\n", FnPtrArray[1](1.0, 2.0));  // Works
    printf("%d\n\n", FnPtrArray[1](1, 2));      // Wrong argument types
    printf("%d\n\n", FnPtrArray[1](1.0));       // Wrong number of args

    return 0;
}

以下是指向above code on


1 这与C ++有很大不同,其中一个空的形式参数列表 dim 是没有参数。

In C, an empty parameter list in a function declaration does not mean that the function takes no argument; rather, it means that it takes an unspecified number of arguments.1

So, syntactically at least, you can specify an array of function pointers, each with an unspecified number of arguments (but a fixed return type), like this: bool (*FnPtrArray[100])();. You can then assign, to different elements of such an array, addresses of functions with different argument types and numbers. However, there can then be no compile-time check that those functions are called correctly, or any implicit conversion of given argument types to the 'correct' forms.

The code below illustrates this (but note that I do not recommend using code like this, because of the inherent dangers that passing incorrect arguments can cause):

#include <stdio.h>
#include <stdbool.h>

bool Foo(int a) {
    printf("Foo: %d ...\n", a);
    return a % 2;
}

bool Bar(double x, double y) {
    printf("Bar: %5.3lf %5.3lf...\n", x, y);
    return x < y;
}

int main()
{
    bool (*FnPtrArray[100])();

    // So we can't tell at compile time which elements point where ...
    printf("Enter a number: ");
    int n = 42;
    scanf("%d", &n);
    if (n % 2) {
        FnPtrArray[0] = Foo;
        FnPtrArray[1] = Bar;
    }
    else {
        FnPtrArray[1] = Foo;
        FnPtrArray[0] = Bar;
    }

    // Notes assuming given "n" is odd ...
    printf("%d\n\n", FnPtrArray[0](3));         // Works
    printf("%d\n\n", FnPtrArray[0](3.0));       // Wrong argument type
    printf("%d\n\n", FnPtrArray[1](1.0, 2.0));  // Works
    printf("%d\n\n", FnPtrArray[1](1, 2));      // Wrong argument types
    printf("%d\n\n", FnPtrArray[1](1.0));       // Wrong number of args

    return 0;
}

Here's a link to the above code on Compiler Explorer, for those who want to test with various compilers and settings.


1 This is very different from C++, where an empty formal parameter list does mean no argument.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文