函数的参数在不同的文件中被调用

时间:2015-07-29 08:55:04

标签: c function-pointers typedef

完整的测试代码如下所示

头文件(例如,a.h)定义以下代码:

typedef uint8_t EnrollT(uint16_t test1, uint16_t test2);
typedef void ChangeT(uint64_t post1, uint8_t post2);
struct ClusterT * ClientAlloc(EnrollT *, ChangeT *);

在我的一个c(比如,test1.c)文件中包含如下所示的a.h:

void Enroll(uint16_t test1, uint16_t test2){
     printf("Happy Enrolling");
}

void Change(uint64_t post1, uint8_t post2){
     printf("Happy Changing");
}

struct ClusterT * ClientAlloc(EnrollT *p, ChangeT *q)
{
    p = Enroll;
    q = Change;

    return something;
}

上面的代码编译好了,但是,在下面的代码中,我在另一个包含a.h的c文件(比如test2.c)中有点困惑。

void priTest(){
    somethingOkay = ClientAlloc( ???? );
}

在这种情况下,我应该在test2.c中的ClientAlloc()函数中添加哪些参数?

@dasblinkenlight

要清楚,我已经修改了代码,如下所示:

在标题

typedef uint8_t EnrollT(uint16_t test1, uint16_t test2);
typedef void ChangeT(uint64_t post1, uint8_t post2);
struct ClusterT * ClientAlloc(EnrollT *, ChangeT *);

在test1.c中

void Enroll(uint16_t test1, uint16_t test2){
     printf("Happy Enrolling");
}

void Change(uint64_t post1, uint8_t post2){
     printf("Happy Changing");
}

struct ClusterT * ClientAlloc(EnrollT *p, ChangeT *q)
{
    p = Enroll;
    q = Change;

    return something;
}

在test2.c中

uint8_t Enroll(uint16_t test1, uint16_t test2);
void Change(uint64_t post1, uint8_t post2);


void priTest(){
    somethingOkay = ClientAlloc( Enroll, Change );
}

@Joachim Pileborg

我修改了我的代码,如下所示,如果我误解你在回复中的意思,请告诉我。

在我的标题a.h

typedef uint8_t (*EnrollT)(uint16_t test1, uint16_t test2);
typedef void (*ChangeT)(uint64_t post1, uint8_t post2);
struct ClusterT * ClientAlloc(EnrollT *, ChangeT *);

在test1.c中

void Enroll(uint16_t test1, uint16_t test2){
     printf("Happy Enrolling");
}

void Change(uint64_t post1, uint8_t post2){
     printf("Happy Changing");
}

struct ClusterT * ClientAlloc(EnrollT *p, ChangeT *q)
{
    *p = Enroll;
    *q = Change;

    return something;
}

在test2.c中

EntrollT enroll;
ChangeT  change;

void priTest(){
    somethingOkay = ClientAlloc( &enroll, &change );
}

2 个答案:

答案 0 :(得分:2)

首先,如果你想要,例如EnrollT成为函数的指针,然后你需要声明它:

typedef uint8_t (*EnrollT)(uint16_t test1, uint16_t test2);

其次,您使用的函数定义 not 与您创建的类型别名相匹配,因此虽然它可能在没有错误的情况下构建,但您的代码仍然存在问题应该导致编译器警告,如果你没有收到警告,那么你应该在构建时启用更多警告。警告通常表明您做了一些您不应该做的事情,这可能会导致未定义的行为和可能的崩溃。并且不要通过一些简单的转换来修复警告,尝试找出警告的根本原因,并修改它。

第三,以及您提出的问题。如果您在第一段中进行更改,那么它很简单:

EntrollT enroll;
ChangeT  change;

ClientAlloc(&enroll, &change);

但是,这是简单部分,因为您还必须修改ClientAlloc函数,以便能够处理模拟的通过引用传递

struct ClusterT * ClientAlloc(EnrollT *p, ChangeT *q)
{
    // Note use of dereference operator `*` here
    *p = Enroll;
    *q = Change;

    return something;
}

至少如果您要将pq设置为EnrollChange函数,那么您可以从调用{{1}的代码中调用它们}。如果你想做什么,而是传入函数指针以便被例如调用。 ClientAlloc然后您需要进行更多修改,例如保存传递给函数的指针而不是分配给它们。

如果你想传入函数指针而不是ClientAlloc使用,那么你不应该在源文件中定义函数,而是在它们应该在的位置定义它们,在源中调用 ClientAlloc,那么你应该有例如

标题文件:

ClientAlloc

Test1.c:

typedef uint8_t (*EnrollT)(uint16_t test1, uint16_t test2);
typedef void (*ChangeT)(uint64_t post1, uint8_t post2);

struct ClusterT * ClientAlloc(EnrollT, ChangeT);

最后你的test2.c:

// Declare the function pointers
// (static so the won't be exported)
static EnrollT enroll;
static ChangeT change;

struct ClusterT * ClientAlloc(EnrollT e, ChangeT c)
{
    enroll = e;
    change = c;

    ...
}

答案 1 :(得分:1)

您无法使用EnrollChange制作EnrollTChangeT函数指针,因为它们不兼容。为了使函数匹配,它们必须具有与typedef中声明的函数相同的签名:

uint8_t Enroll(uint16_t test1, uint16_t test2){
    printf("Happy Enrolling");
    return 0;
}
void Change(uint64_t post1, uint8_t post2){
     printf("Happy Changing");
}

现在您可以将这些功能传递给ClientAlloc

somethingOkay = ClientAlloc(Enroll, Change);

由于调用发生在另一个文件中,您需要在文件顶部转发声明您的函数:

uint8_t Enroll(uint16_t test1, uint16_t test2);
void Change(uint64_t post1, uint8_t post2);