//函数指针做函数参数
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<Windows.h>
/*
函数指针做函数参数
实现了2大功能:1.定义了一个指针类型,分配了4个字节大小的内存空间
2.规定了调用函数的参数列表,和返回值
正向调用:通过window自带系统函数库调用dll文件,获取dll文件中的函数地址,执行函数
反向调用:通过函数指针,在另一个函数里调用别的函数
*/
void main(){
//正向调用
//定义句柄----HINSTANCE头文件是Windows.h
HINSTANCE hinstance;
//定义函数指针类型
typedef int(*SocketInitType)(void** /*out*/);
typedef int(*SocketSendType)(void *, unsigned char *, int );
typedef int(*SocketRevType)(void *, unsigned char **, int *);
typedef int(*SocketDestory)(void **);
int ret = 0;
void *handle=NULL;
//准备发送报文
char *sendstr = "dddddd";
int buflen1 = strlen(sendstr) + 1;
//接受报文
char *revstr = NULL;
int buflen2 = 0;
//严重注意(第一次花费了半小时):在使用LoadLibrary宏定义的时候一定要设置字符集是未设置,不然c语言编译器不识别文件路径
//具体设置:项目右键--属性--配置属性--常规--字符集--未设置
hinstance = LoadLibrary("E:/L001.dll");
if (hinstance==NULL)
{
printf("获取文件地址失败!\n");
}
//获取函数地址
SocketInitType pf = (SocketInitType)GetProcAddress(hinstance, "cltSocketInit");
if (pf==NULL)
{
printf("获取函数指针失败!\n");
return;
}
SocketSendType pf2 = (SocketSendType)GetProcAddress(hinstance, "cltSocketSend");
if (pf2 == NULL)
{
printf("获取函数指针失败!\n");
return;
}
SocketRevType pf3 = (SocketRevType)GetProcAddress(hinstance, "cltSocketRev");
if (pf3 == NULL)
{
printf("获取函数指针失败!\n");
return;
}
SocketDestory pf4 = (SocketDestory)GetProcAddress(hinstance, "cltSocketDestory");
if (pf4 == NULL)
{
printf("获取函数指针失败!\n");
return;
}
ret = pf(&handle);
if (ret!=0)
{
printf("句柄初始化失败!\n");
goto AAA;
}
ret = pf2(handle, (unsigned char*)sendstr, buflen1);
if (ret!=0)
{
printf("报文发送失败!\n");
}
ret = pf3(handle, (unsigned char**)&revstr, &buflen2);
if (ret!=0)
{
printf("报文接受失败!\n");
}
//打印接受的报文
printf(revstr);
//释放报文内存
free(revstr);
ret = pf4(&handle);
if (ret != 0)
{
printf("释放句柄失败!\n");
}
AAA:
system("pause");
}