一个函数的参数在不同的文件中被调用
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 );
}
您不能使用 Enroll
和 Change
来创建 EnrollT
和 ChangeT
函数指针,因为它们不兼容。为了使函数匹配,它们必须具有与在 typedef
s:
中声明的函数相同的签名
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;
}
至少如果你想将 p
和 q
设置为函数 Enroll
和 Change
,那么你可以从调用 [= 的代码中调用它们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);
}
完整的测试代码如下
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 );
}
您不能使用 Enroll
和 Change
来创建 EnrollT
和 ChangeT
函数指针,因为它们不兼容。为了使函数匹配,它们必须具有与在 typedef
s:
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;
}
至少如果你想将 p
和 q
设置为函数 Enroll
和 Change
,那么你可以从调用 [= 的代码中调用它们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);
}