VC++Native Wifi API 3---GOTOのリソース解放時の役割
2632 ワード
GOTO文は評判が悪く、私たちの先生は簡単に使わないように教えてくれました.
C++ジャンプ文はgoto,break,continueの3つである.それらはただの道具で、問題は道具のせいにすることはできないと思います.問題は人にあります.
ポインタのようにgotoという無条件ジャンプ文の力は強いが、乱用すれば問題が発生しにくい.
しかし、gotoは確かに2つの選択ではありません.例えば、私が出会ったのは、関数に複数の出口があり、各出口がリソースを解放するとき、解放文を煩わしく書かないよりも、
goto文のようにさっぱりしていないほうがいい.
次の例は、前のNative Wifi APIの記事から取ったもので、私たちのプログラムが常に制御しているwifiのonとoffのため、リソースの解放に注意しなければならない.WlanOpenHandleで言えば、
対称WlanCloseHandlerに注意しないと、プログラムが何回か実行された後にエラーが発生します:ERROR_REMOTE_SESSION_LIMIT_EXCEEDED
公式サイトでは、Too many handles have been issued by the serverと解釈されています.
したがって、各API呼び出し後、戻り値を確認し、エラーが発生した場合、プログラムは下向きに実行されなくなります.returnの前に、リソースを解放する必要があります.出口が多い場合は同じコードをたくさん書きます
イライラして読みにくく、コードが急速に膨張します.しかしgotoを使用すると、問題は簡単になります.簡単な例を見てください.
最後にgotoは多重ループから飛び出すためにも使われる.しかし、内層から外層にジャンプするしかなく、不可逆的に動作することに注意しなければならない.
C++ジャンプ文はgoto,break,continueの3つである.それらはただの道具で、問題は道具のせいにすることはできないと思います.問題は人にあります.
ポインタのようにgotoという無条件ジャンプ文の力は強いが、乱用すれば問題が発生しにくい.
しかし、gotoは確かに2つの選択ではありません.例えば、私が出会ったのは、関数に複数の出口があり、各出口がリソースを解放するとき、解放文を煩わしく書かないよりも、
goto文のようにさっぱりしていないほうがいい.
次の例は、前のNative Wifi APIの記事から取ったもので、私たちのプログラムが常に制御しているwifiのonとoffのため、リソースの解放に注意しなければならない.WlanOpenHandleで言えば、
対称WlanCloseHandlerに注意しないと、プログラムが何回か実行された後にエラーが発生します:ERROR_REMOTE_SESSION_LIMIT_EXCEEDED
公式サイトでは、Too many handles have been issued by the serverと解釈されています.
したがって、各API呼び出し後、戻り値を確認し、エラーが発生した場合、プログラムは下向きに実行されなくなります.returnの前に、リソースを解放する必要があります.出口が多い場合は同じコードをたくさん書きます
イライラして読みにくく、コードが急速に膨張します.しかしgotoを使用すると、問題は簡単になります.簡単な例を見てください.
// ManageWirelessNetwork.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <shellapi.h>
#include <wlanapi.h>
// Need to link with shell32.lib
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "wlanapi.lib")
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwResult = 0;
DWORD dwMaxClient = 2;
DWORD dwCurVersion = 0;
HANDLE hClient = NULL;
PWLAN_INTERFACE_INFO_LIST pIfList = NULL;
PWLAN_INTERFACE_INFO pIfInfo = NULL;
dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);
if (dwResult != ERROR_SUCCESS) {
wprintf(L"WlanOpenHandle failed with error: %u
", dwResult);
return false;
}
dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);
if (dwResult != ERROR_SUCCESS) {
wprintf(L"WlanEnumInterfaces failed with error: %u
", dwResult);
goto RELEASE_RESOURCE;
}
WLAN_PHY_RADIO_STATE state;
state.dwPhyIndex = 0;
state.dot11SoftwareRadioState = dot11_radio_state_on;//off here too.
PVOID pData = &state;
dwResult = WlanSetInterface(hClient,&pIfList->InterfaceInfo[0].InterfaceGuid,
wlan_intf_opcode_radio_state,sizeof(WLAN_PHY_RADIO_STATE),pData,NULL);
if(dwResult == ERROR_SUCCESS)
{
wprintf(L"set state success!
");
}
else
{
wprintf(L"set state failed!err is %d
",dwResult);
}
RELEASE_RESOURCE:
if(hClient)
{
WlanCloseHandle(hClient,NULL);
hClient = NULL;
}
if(pIfList)
{
WlanFreeMemory(pIfList);
pIfList = NULL;
}
if(pIfInfo)
{
WlanFreeMemory(pIfInfo);
pIfInfo = NULL;
}
return 0;
}
最後にgotoは多重ループから飛び出すためにも使われる.しかし、内層から外層にジャンプするしかなく、不可逆的に動作することに注意しなければならない.