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

时间:2022-02-18 16:02:49

The complete testing code shown in the following

完整的测试代码如下所示

The header file ( say, a.h ) defines the following codes:

头文件(例如,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 *);

In one of my c ( say, test1.c) files which includes a.h shown below:

在我的一个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;
}

Above codes gets compiled okay, however, in the following code, I am a little bit confused in the another c file ( say, test2.c ) which includes a.h as well.

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

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

In this case, what arguments should I add in my ClientAlloc() function in test2.c ?

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


@dasblinkenlight

To be clear, I've modified the code as shown in the following:

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

In the 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 *);

In 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;
}

In 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

I modifed my code as shown in the following, please let me know if I misunderstand what you mean in your reply.

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

In my header a.h

在我的标题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 *);

In 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;
}

In test2.c

EntrollT enroll;
ChangeT  change;

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

2 个解决方案

#1


1  

You cannot use Enroll and Change to make an EnrollT and ChangeT function pointers, because they are incompatible. In order for the functions to match, they must have the same signatures as the functions declared in your typedefs:

您不能使用Enroll和Change来生成EnrollT和ChangeT函数指针,因为它们不兼容。为了使函数匹配,它们必须具有与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");
}

Now you can pass these functions to ClientAlloc:

现在您可以将这些函数传递给ClientAlloc:

somethingOkay = ClientAlloc(Enroll, Change);

Since the call happens in a different file, you need to forward-declare your functions at the top of the file:

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

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

#2


2  

First of all, if you want e.g. EnrollT to be a pointer to a function, then you need to declare it as such:

首先,如果你想要,例如EnrollT是一个指向函数的指针,然后你需要声明它:

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

Secondly, the functions definitions you use do not match the type-alias you create, so while it might build without errors, you still have problems in your code that should cause compiler warnings, and if you don't get warnings then you should enable more warnings when building. Warnings are often a sign of you doing something you should not do, that might lead to undefined behavior and possible crashes. And don't fix warnings by just some simple casting, try to find out the root cause of the warnings, and fix that instead.

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

Thirdly, and the problem you're asking about. If you make the change in the first paragraph, then it's simple:

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

EntrollT enroll;
ChangeT  change;

ClientAlloc(&enroll, &change);

However, that is the simple part, because you have to modify the ClientAlloc function too, to be able to handle the emulated pass by reference handling:

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

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

    return something;
}

At least if you want to set p and q to the functions Enroll and Change, so you could call them from the code that called ClientAlloc. IF that's not what you want to do, but instead pass in functions pointer to be called by e.g. ClientAlloc then you need to make more modifications, like saving the pointer passed to the function instead of assigning to them.

至少如果你想将p和q设置为Enroll and Change函数,那么你可以从调用ClientAlloc的代码中调用它们。如果这不是你想要做的,而是传入函数指针,以便通过例如调用。 ClientAlloc然后您需要进行更多修改,例如保存传递给函数的指针而不是分配给它们。


If you want to pass in function pointer to be used by ClientAlloc instead, then you should not define the functions inside that source file, instead define them where they are supposed to be, in the source calling ClientAlloc, then you should have e.g.

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

Header file:

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;

    ...
}

And finally your test2.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);
}

#1


1  

You cannot use Enroll and Change to make an EnrollT and ChangeT function pointers, because they are incompatible. In order for the functions to match, they must have the same signatures as the functions declared in your typedefs:

您不能使用Enroll和Change来生成EnrollT和ChangeT函数指针,因为它们不兼容。为了使函数匹配,它们必须具有与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");
}

Now you can pass these functions to ClientAlloc:

现在您可以将这些函数传递给ClientAlloc:

somethingOkay = ClientAlloc(Enroll, Change);

Since the call happens in a different file, you need to forward-declare your functions at the top of the file:

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

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

#2


2  

First of all, if you want e.g. EnrollT to be a pointer to a function, then you need to declare it as such:

首先,如果你想要,例如EnrollT是一个指向函数的指针,然后你需要声明它:

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

Secondly, the functions definitions you use do not match the type-alias you create, so while it might build without errors, you still have problems in your code that should cause compiler warnings, and if you don't get warnings then you should enable more warnings when building. Warnings are often a sign of you doing something you should not do, that might lead to undefined behavior and possible crashes. And don't fix warnings by just some simple casting, try to find out the root cause of the warnings, and fix that instead.

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

Thirdly, and the problem you're asking about. If you make the change in the first paragraph, then it's simple:

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

EntrollT enroll;
ChangeT  change;

ClientAlloc(&enroll, &change);

However, that is the simple part, because you have to modify the ClientAlloc function too, to be able to handle the emulated pass by reference handling:

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

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

    return something;
}

At least if you want to set p and q to the functions Enroll and Change, so you could call them from the code that called ClientAlloc. IF that's not what you want to do, but instead pass in functions pointer to be called by e.g. ClientAlloc then you need to make more modifications, like saving the pointer passed to the function instead of assigning to them.

至少如果你想将p和q设置为Enroll and Change函数,那么你可以从调用ClientAlloc的代码中调用它们。如果这不是你想要做的,而是传入函数指针,以便通过例如调用。 ClientAlloc然后您需要进行更多修改,例如保存传递给函数的指针而不是分配给它们。


If you want to pass in function pointer to be used by ClientAlloc instead, then you should not define the functions inside that source file, instead define them where they are supposed to be, in the source calling ClientAlloc, then you should have e.g.

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

Header file:

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;

    ...
}

And finally your test2.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);
}