总结学习 —— 前置定义

来源:互联网 发布:lable java 编辑:程序博客网 时间:2024/06/08 08:30
当在一个很大的工程中,需要隐藏结构体中的内容,或者中间件给用户的接口,不希望用户知道结构体的内容形式,那么,请使用前置定义。先上一个小例子:
//main.c#include <stdio.h>#include "test.h"struct Test *test;void main(void){    int ret;    test = Init();    Print(test);    printf("the end!\n");}
//test.h#ifndef _TEST_H_#define _TEST_H_struct Test *Init(void);void Print(struct Test * test);#endif
//test.c#include <stdio.h>#include <stdlib.h>struct Test{    char num;    int  flag;};typedef struct Test *TEST;TEST Init(void){    TEST test;    test = (TEST)malloc(sizeof(struct Test));    test->flag = 9;    test->num  = 4;    rerurn test;}void Print(TEST test){    printf("the result is %d,%d!\n", test->num, test->flag);    free(test);}
例子比较简单,就三个文件,其中main.c和test.h可以提供给别人,为了隐藏struct Test结构体中的内容,将test.c文件编译成库文件。编译过程:第一步:gcc -o libtest.so -fPIC -shared test.c第二步:gcc -o test main.c -L ./ -l test第三步:export LD_LIBRARY_PATH=./第四步:执行程序 ./test不出什么意外会打印出正确结果,以上操作不需要root权限。这时候,你将test.c文件移走,别人就不会知道struct Test中到底有什么东西了,能够在一定程度上实现结构体数据的保密。

注意点:
(1)在main.c中定义结构体的时候,要定义成指针型变量;如果定义成为非指针变量(如struct Test test),那么会报出“incomplete type”的错误。因为定义成为非指针变量的话,程序在编译的时候会给变量分配空间,但是该变量是一个“前置定义”的变量,不知道包还有什么元素,所以会报错;定义成为一个指针后,直接分配一个地址完事。

(2)既然是“incomplete type”,在main.c中是不能够使用sizeof求出结构体的大小,即sizeof(struct Test)会报错。

(3)在main函数中定义的test指向NULL,所以不能够直接使用,通过malloc分配内存后使用。

(4)切记不要这么用:
void Init(sruct Test *test);

void Init(struct Test *test)
{

test = (struct Test *)malloc(sizeof(struct Test));

}
这样的话,在main函数中调用Init函数,不会得到正确的结果。

敲代码的路上需要积累,共勉。

1 0