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

The arguments of a function gets called in different files

完整的测试代码如下

header 文件(例如,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

为了清楚起见,我修改了代码,如下所示:

在header

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

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

在我的headera.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 );
}

您不能使用 EnrollChange 来创建 EnrollTChangeT 函数指针,因为它们不兼容。为了使函数匹配,它们必须具有与在 typedefs:

中声明的函数相同的签名
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);

首先,如果你想要,例如EnrollT 成为函数的 指针 ,那么你需要这样声明它:

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

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

第三,你问的问题。如果您在第一段中进行更改,则很简单:

EntrollT enroll;
ChangeT  change;

ClientAlloc(&enroll, &change);

但是,那是 简单的 部分,因为您还必须修改 ClientAlloc 函数,才能处理模拟的 pass通过引用处理:

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

    return something;
}

至少如果你想将 pq 设置为函数 EnrollChange,那么你可以从调用 [= 的代码中调用它们17=]。如果那是 不是 你想做的,而是传递函数指针以供调用。 ClientAlloc 那么你需要做更多的修改,比如保存传递给函数的指针而不是赋值给它们。


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

头文件:

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:

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

    ...
}

最后是你的 test2.c:

uint8_t my_enroll_function(uint16_t test1, uint16_t test2)
{
    ...
}

void my_change_function(uint64_t post1, uint8_t post2)
{
    ...
}

int main(void)
{
    ClientAlloc(my_enroll_function, my_change_function);
}