函数指针

来源:互联网 发布:港澳资讯点金手软件 编辑:程序博客网 时间:2024/06/06 05:00


回调函数

1、函数类型基础

函数三要素:名称、参数、返回值

C语言中的函数有自己特定的类型

C语言中通过typedef为函数类型重命名

typedef type name(parameter list)

typedef int f(int, int);

typedef void p(int);

函数指针

函数指针用于指向一个函数

函数名是执行函数体的入口地址

1)可通过函数类型定义函数指针:FuncType* pointer;

2)也可以直接定义:type(*pointer)(parameter list);

pointer为函数指针变量名

type为指向函数的返回值类型

parameterlist为指向函数的参数类型列表


#include <stdio.h>typedef int Func(int, int);typedef int (*PFunc)(int, int);int add(int a,int b){    return a + b;}int main(int argc, char* argv[]){    PFunc func = add;    int res = func(1, 2);    printf("res = %d\n",res);    Func *f = add;    res = (*f)(1, 2);    printf("res = %d\n",res);    return 0;}


2、函数指针做函数参数

  1. 指针做函数参数pk函数指针做函数参数

回忆指针做函数参数

一级指针做函数参数、二级、三级

  1. 函数指针做函数参数

当函数指针做为函数的参数,传递给一个被调用函数,

被调用函数就可以通过这个指针调用外部的函数,这就形成了回调

int add(int a, int b);void libfun(int (*pDis)(int a, int b));int main(void){    libfun(add);    return 0;}int add(int a, int b){return a + b;}void libfun(int (*pDis)(int a, intb)){    int a, b;    a = 1;    b = 2;    printf("%d", pDis(a, b));}

现在这几个函数是在同一个文件当中

假如

int libfun(int (*pDis)(int a, intb))

是一个库中的函数,就只有使用回调了,通过函数指针参数将外部函数地址传入

来实现调用


函数add的代码作了修改,也不必改动库的代码,就可以正常实现调用

便于程序的维护和升级


3、函数指针正向调用

  1. 函数指针做函数参数,调用方式

被调用函数和主调函数在同一文件中(用来教学,没有任何意义)

2、函数指针做函数参数

被调用函数和主调函数不在同一个文件中、模块中。

难点:理解被调用函数是什么机制被调用起来的。框架

框架提前设置了被调用函数的入口(框架提供了第三方模块入口地址的集成功能)

框架具备调用第三方模块入口函数

  1. 练习


typedef int (*EncDataFunc)(unsignedchar *inData,int inDataLen,unsigned char *outData,int*outDataLen,void *Ref, int RefLen);


int MyEncDataFunc(unsigned char*inData,int inDataLen,unsigned char *outData,int *outDataLen,void*Ref, int RefLen)

{

int rv = 0;

char *p = "222222222222";

strcpy(outData, p);

*outDataLen = strlen(p);

return rv;

}


int Send_Data(EncDataFuncencDataFunc, unsigned char *inData, int inDataLen, unsigned char*outData, int *outDatalen)

{

int rv = 0;

if (encDataFunc != NULL)

{

rv = encDataFunc(inData,inDataLen, outData, outDatalen, NULL, 0);

if (rv != 0)

{

printf("func encDataFunc()err.\n");

return rv;

}

}

return rv;

}


int main()

{

int rv = 0;


EncDataFunc encDataFunc = NULL;

encDataFunc = MyEncDataFunc;


// 第一个调用

{

unsigned char inData[2048];

int inDataLen;

unsigned char outData[2048];

int outDatalen;

strcpy(inData, "1111");

inDataLen = strlen(inData);

rv = encDataFunc(inData,inDataLen,outData, &outDatalen, NULL, 0);

if (rv != 0)

{

printf("edf err .....\n");

}

else

{

printf("edf ok \n");

printf("%s \n",outData);

}

}


{

unsigned char inData[2048];

int inDataLen;

unsigned char outData[2048];

int outDatalen;

strcpy(inData, "3333");

inDataLen = strlen(inData);

rv = Send_Data(MyEncDataFunc,inData, inDataLen, outData, &outDatalen);

if (rv != 0)

{

printf("func Send_Dataerr:%d", rv);

return rv;

}

printf("%s \n",outData);

}


getchar();

}

4、函数指针反向调用

回调函数

利用函数指针实现的一种调用机制

具体任务的实现者,可以不知道什么时候被调用

回调函数是利用函数指针实现的一种调用机制


回调机制原理

当具体事件发生时,调用者通过函数指针调用具体函数

回调机制的将调用者和被调函数分开,两者互不依赖

任务的实现和 任务的调用 可以耦合 (提前进行接口的封装和设计)

需要重新审视dll和其他第三方厂商接口之间的关系

动态库可以集成第三方厂商的业务功能

动态库(框架)不经常改动,能兼容后来的业务模型,2010年写的代码能调用2020写的代码,用到多态

动态库和第三方业务模型模块之间 松耦合

//动态库变成框架需要做的工作

//1 第三方业务入口传进来(回调函数的入口地址传进来)


//2 加密解密 业务模型抽象

//实现动态库 加密解密业务模型抽象

通过定义函数指针类型;函数指针做函数参数实现



0 0