本程序通过调用动态链接库获取局域网内可用IP。
为了获取动态链接库中的结构体类型变量,可以在调用动态链接库时传入相同结构的结构体参数。
例:
//动态链接库,通过调用IPscan()可以获得参数值:ip_scan_reply
DLL
.h
typedef struct
{
char echo_ip[100][16];
BOOL error_message;
}IP_SCAN_REPLY;
//声明函数为导出函数返回参数、形参类型要和函数本身保持一致
extern "C" _declspec(dllexport) void IPscan(IP_SCAN_REPLY * ip_scan_reply);
.cpp
void IPscan(IP_SCAN_REPLY * ip_scan_reply)
{
/**************
函数体
**************/
(* ip_scan_reply) = result;
return;
}
下面是调用上述动态链接库并获取动态链接库执行结束后的参数
ip_scan_reply
的方法。
//MFC调用动态链接库
//定义相同结构的结构体
typedef struct
{
char echo_ip[100][16];
BOOL error_message;
}IP_SCAN_REPLY;
//按钮事件
void CLocal_Area_Network_IP_ScanDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
//定义dll的句柄
HINSTANCE hDll = NULL;
//定义结构体变量,用于存储从动态链接库返回的参数
IP_SCAN_REPLY echo_reply;
//定义函数的结构要和动态链接库中导出函数保持一致
typedef void (* Function)(IP_SCAN_REPLY *);
Function LanIPscan;
hDll = LoadLibrary(_T("Local_Area_Network_IP_ScanDLL.dll"));
if(!hDll)
{
AfxMessageBox(_T("动态链接库加载失败!"));
return;
}
LanIPscan = (Function)GetProcAddress(hDll, "IPscan");
if(LanIPscan == NULL)
{
AfxMessageBox(_T("获取函数失败!"));
return;
}
memset(&echo_reply, 0, sizeof(echo_reply));
//将参数传入动态链接库
LanIPscan(&echo_reply);
FreeLibrary(hDll);
return;
}
通过动态链接库获取的参数是形如"192.168.1.3"、"192.168.1.211"等点分十进制IP字符串,在上面的程序中,是将字符串通过转换之后拆分成单个字符存储在数组中,如下:
echo_ip[0][0] = '1';
echo_ip[0][1] = '9';
echo_ip[0][2] = '2';
echo_ip[0][3] = '.';
.
.
.
echo_ip[0][15] = '\0';
因此程序中定义的结构体理论上也可定义为如下形式:
DLL
typedef struct
{
string echo_ip[100];
BOOL error_message;
}IP_SCAN_REPLY;
MFC
typedef struct
{
CString echo_ip[100];
BOOL error_message;
}IP_SCAN_REPLY;
/*************************
存储方式如下:
echo_ip[0] = "192.168.1.2";
echo_ip[1] = "192.168.1.211";
.
.
.
**************************/
但在实际应用时,在调用动态链接库执行完下面的语句:
LanIPscan(&echo_reply);
并不能获取相应的参数值,虽然单步运行之后,动态链接库中和调用主体中的参数地址中的值为正确的值,但调用主体中的变量却出现“字符串读取错误”。