最近写代码遇到个问题,一个库有一个.h文件和.c文件,一般我们根据.h里的内容进行函数调用就行了,但是今天遇到的情况是,有一个结构体和结构体相关的操作函数是在.c里的,.h文件里没有
如下这种,mystruct.h和mystruct.c,MyStruct2的定义和相关函数只存在于mystruct.c里,
// mystruct.h
#ifndef MY_STRUCT_H_
#define MY_STRUCT_H_
typedef struct MyStruct1_ {
int d1;
int d2;
} MyStruct1;
MyStruct1 *createMyStruct1();
void initStruct1(MyStruct1 *ptr);
#endif
// mystruct.c #include#include "mystruct.h" MyStruct1 *createMyStruct1() { return (MyStruct1 *)malloc(sizeof(MyStruct1)); } void initStruct1(MyStruct1 *ptr) { if (ptr) { ptr->d1 = 1; ptr->d2 = 1; } } typedef struct MyStruct2_ { char d1; char d2; } MyStruct2; MyStruct2 *createMyStruct2() { return (MyStruct2 *)malloc(sizeof(MyStruct2)); } void initStruct2(MyStruct2 *ptr) { if (ptr) { ptr->d1 = 1; ptr->d2 = 1; } }
二 解决办法
对于函数比较好解决,在main.c里使用extern声明一下就行了,那么结构体呢?同样的,也声明一下,如下这样,
#include "mystruct.h"
typedef struct MyStruct2_ {
char d1;
char d2;
} MyStruct2;
extern MyStruct2 *createMyStruct2();
extern void initStruct2(MyStruct2 *ptr);
int main()
{
MyStruct1 *pObj1 = createMyStruct1();
initStruct1(pObj1);
MyStruct2 *pObj2 = createMyStruct2();
initStruct2(pObj2);
return 0;
}
这个结构体声明和C++里类的前置声明一样,main.c里只能使用MyStruct2的指针,相关操作函数也是只能操作该指针。
这里需要注意一个问题:如果MyStruct2的结构比较复杂怎么办?例如其元素里又使用了别的类型,这个类型也没有在头文件里定义,那么还要再声明一下,似乎很麻烦。
三 更加简单的声明方法
其实可以很简单,在main.c里只需要结构体的声明,并不关心其内部的元素,那么可以改成如下这样的声明,
#include "mystruct.h"
typedef struct {} MyStruct2; // 简化声明
extern MyStruct2 *createMyStruct2();
extern void initStruct2(MyStruct2 *ptr);
int main()
{
MyStruct1 *pObj1 = createMyStruct1();
initStruct1(pObj1);
MyStruct2 *pObj2 = createMyStruct2();
initStruct2(pObj2);
return 0;
}
根本原理:只要保证main.c可以编译通过,然后保证MyStruct2的实体在别的地方有定义,最后链接的时候可以找到就行了。



