函数指针作为函数参数的用法总结及其意义--首次前向调用
例:
有个socketclient.dll,用dependency walker可以查看到dll的方法。
第一步 Load DLL
HINSTANCE hInstance;
string pathStr= "socketclient.dll";
LPCSTR sss = pathStr.c_str();
hInstance =LoadLibrary("socketclient.dll");
if (hInstance == NULL)
{
printf("LoadLibrary() 失败");
return 0;
}
在这里注意编码的问题。
右键属性如下图:
将字符集修改为使用多字节字符集。
如果使用Unicode字符集则需要做修改,Unicode时,LoadLibrary的参数是LPCWSTR。所以需要做转化。
LPCWSTR stringToLPCWSTR(string orig)
{
size_t origsize = orig.length() + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length() - 1));
mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
return wcstring;
}
int main()
{
HINSTANCE hInstance;
string pathStr= "socketclient.dll";
LPCTSTR sss = stringToLPCWSTR(pathStr);
hInstance =LoadLibrary(sss);
if (hInstance == NULL)
{
printf("LoadLibrary() 失败");
return 0;
}
}
第二步 声明函数指针类型
//客户端初始化 获取handle上下
//声明一个函数指针类型
typedef int(*CltSocketInit)(void **handle /*out*/);
//客户端发报文
typedef int(*CltSocketSend)(void *handle /*in*/, unsigned char *buf /*in*/, int buflen /*in*/);
//客户端收报文
typedef int(*CltSocketRev)(void *handle /*in*/, unsigned char *buf /*in*/, int *buflen /*in out*/);
//客户端释放资源
typedef int(*CltSocketDestory)(void *handle/*in*/);
第三步 实现函数的调用。
CltSocketInit cltSocketInit = (CltSocketInit)::GetProcAddress(hInstance, "cltSocketInit");
if (cltSocketInit == NULL)
{
return 0;
}
CltSocketSend cltSocketSend = (CltSocketSend)::GetProcAddress(hInstance, "cltSocketSend");
CltSocketRev cltSocketRev = (CltSocketRev)::GetProcAddress(hInstance, "cltSocketRev");
CltSocketDestory cltSocketDestory = (CltSocketDestory)::GetProcAddress(hInstance, "cltSocketDestory");
//执行动态库函数调用
unsigned char buf[128];
int buflen = 128;
unsigned char outbuf[4096];
int outbuflen = 4096;
strcpy((char *)buf, "aaaaaaaaaafffffffffdddddd");
buflen = 9;
void *handle = NULL;
int ret = 0;
ret = cltSocketInit(&handle);
ret = cltSocketSend(handle, buf, buflen);
ret = cltSocketRev(handle, outbuf, &outbuflen);
ret = cltSocketDestory(handle);
if (memcmp(buf, outbuf, outbuflen) == 0)
{
printf("发送数据和接受的数据一样 ok\n");
}
else
{
printf("发送数据和接受的数据不一样\n");
}
完整代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#include <iostream>
using namespace std;
//客户端初始化 获取handle上下
//声明一个函数指针类型
typedef int(*CltSocketInit)(void **handle /*out*/);
//客户端发报文
typedef int(*CltSocketSend)(void *handle /*in*/, unsigned char *buf /*in*/, int buflen /*in*/);
//客户端收报文
typedef int(*CltSocketRev)(void *handle /*in*/, unsigned char *buf /*in*/, int *buflen /*in out*/);
//客户端释放资源
typedef int(*CltSocketDestory)(void *handle/*in*/);
LPCWSTR stringToLPCWSTR(string orig)
{
size_t origsize = orig.length() + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length() - 1));
mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
return wcstring;
}
int main()
{
HINSTANCE hInstance;
string pathStr= "socketclient.dll";
LPCTSTR sss = stringToLPCWSTR(pathStr);
hInstance =LoadLibrary(sss);
if (hInstance == NULL)
{
printf("LoadLibrary() 失败");
return 0;
}
CltSocketInit cltSocketInit = (CltSocketInit)::GetProcAddress(hInstance, "cltSocketInit");
if (cltSocketInit == NULL)
{
return 0;
}
CltSocketSend cltSocketSend = (CltSocketSend)::GetProcAddress(hInstance, "cltSocketSend");
CltSocketRev cltSocketRev = (CltSocketRev)::GetProcAddress(hInstance, "cltSocketRev");
CltSocketDestory cltSocketDestory = (CltSocketDestory)::GetProcAddress(hInstance, "cltSocketDestory");
//执行动态库函数调用
unsigned char buf[128];
int buflen = 128;
unsigned char outbuf[4096];
int outbuflen = 4096;
strcpy((char *)buf, "aaaaaaaaaafffffffffdddddd");
buflen = 9;
void *handle = NULL;
int ret = 0;
ret = cltSocketInit(&handle);
ret = cltSocketSend(handle, buf, buflen);
ret = cltSocketRev(handle, outbuf, &outbuflen);
ret = cltSocketDestory(handle);
if (memcmp(buf, outbuf, outbuflen) == 0)
{
printf("发送数据和接受的数据一样 ok\n");
}
else
{
printf("发送数据和接受的数据不一样\n");
}
return 0;
}
运行结果:
上一篇: C - 内联函数、递归函数、指针函数
下一篇: 了解函数指针和 typedef 函数指针