完整的测试代码如下所示
头文件(例如,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 );
}
答案 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;
}
至少如果您要将p
和q
设置为Enroll
和Change
函数,那么您可以从调用{{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)
您无法使用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");
}
现在您可以将这些功能传递给ClientAlloc
:
somethingOkay = ClientAlloc(Enroll, Change);
由于调用发生在另一个文件中,您需要在文件顶部转发声明您的函数:
uint8_t Enroll(uint16_t test1, uint16_t test2);
void Change(uint64_t post1, uint8_t post2);