「■関数ポインタ改」の編集履歴(バックアップ)一覧はこちら
「■関数ポインタ改」(2012/08/23 (木) 02:38:44) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
*情報
作者名:YouTubeダウンロードし放題
引用元:[[なでしこプログラム掲示板「代用関数ポインタ」>http://nade.jp-pro.net/bbs/bbs3/cbbs.cgi?mode=al2&number=5747&no=0&KLOG=6]]
[[なでしこライブラリ「関数ポインタ」>http://www26.atwiki.jp/isoroku_be/pages/67.html]]
*概要
関数ポインタが最新のなでしこで使えない..って人が多かったので不具合を直しました。
これを使えばなでしこで
-マルチスレッド
-フォームをWinAPIレベルから作成してメッセージループを回す
-非同期な通信
-重い処理の非同期実行
などの高度な処理を実現できます
*[[ソースダウンロード>http://www26.atwiki.jp/isoroku_be?cmd=upload&act=open&pageid=189&file=%E9%96%A2%E6%95%B0%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF+2.05.nako]]
*[[サンプル集ダウンロード>http://www26.atwiki.jp/isoroku_be?cmd=upload&act=open&pageid=189&file=%E9%96%A2%E6%95%B0%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF+2.05.zip]]
*変更点
-ver2.10
+●関数ポインタ作成 でイベントを事前にEVALで登録するように修正(高速化)
-ver2.05
+使いやすいように関数命令を追加
●関数ポインタ取得
●関数ポインタ取得
●関数ポインタ実行
+2個以上関数ポインタを作成した場合のアドレス重複エラーを修正
+関数内での宣言をサポート
+わざわざVirtualAllocでメモリを確保する理由もなく、メモリを解放し忘れる人が多いのでなでしこの「確保」命令に置換(追記: やっぱり実行アクセスの有無が違うらしい... でも実行アクセスがなくてもなぜか実行できるので保留。)
-ver1.01
+グローバルからアクセスできるように
+引数の型を指定できるように
*本体
!変数宣言は必要
!NAKO_GROUP_EXEC=GetProcAddress(GetModuleHandle("dnako.dll"),"nako_group_exec");
!関数ポインタ既定イベント名 = "前処理";
■関数ポインタ
・{イベント}イベント
・{整数}ポインタ
・{配列}引数
・{配列}引数型
・ポケット
・タグ
・{非公開}初期化({グループ}参照)~
型サイズ=空
引数型で反復
対象の型サイズ取得を型サイズに配列追加
バッファに64を確保
バッファの01に$55を「BYTE」でバイナリ設定
バッファの02に$EC8Bを「SHORT」でバイナリ設定
バッファの04に$BAを「BYTE」でバイナリ設定
バッファの05にPOINTER(スタック)を「int」でバイナリ設定
バッファの09に$2A89を「SHORT」でバイナリ設定
バッファの11に$68を「BYTE」でバイナリ設定
バッファの12にPOINTER(関数ポインタ既定イベント名)を「int」でバイナリ設定
バッファの16に$68を「BYTE」でバイナリ設定
バッファの17にADDR(参照)を「int」でバイナリ設定
バッファの21に$B8を「BYTE」でバイナリ設定
バッファの22にNAKO_GROUP_EXECを「int」でバイナリ設定
バッファの26に$D0FFを「SHORT」でバイナリ設定
バッファの28に$058Bを「SHORT」でバイナリ設定
バッファの30にPOINTER(返り値)を「int」でバイナリ設定
バッファの34に$5Dを「BYTE」でバイナリ設定
バッファの35に$C2を「BYTE」でバイナリ設定
バッファの36に(型サイズの配列合計)を「SHORT」でバイナリ設定
ポインタ=POINTER(バッファ)
・{非公開}前処理~
TMPとは整数
TMP=スタック+4
(引数型の配列要素数)回
引数[回数-1]=0
TMP=TMP+型サイズ[回数-1]
MoveMemory(POINTER(引数[回数-1]),TMP,型サイズ[回数-1])
返り値=イベント
・{文字列}バッファ
・{整数}スタック
・{配列}型サイズ
・{整数}返り値
●型サイズ取得(型の)
型=型を大文字変換
型で条件分岐
「CHAR」ならば、(8/8)で戻る
「BYTE」ならば、(8/8)で戻る
「WCHAR」ならば、(16/8)で戻る
「SHORT」ならば、(16/8)で戻る
「WORD」ならば、(16/8)で戻る
「INT」ならば、(32/8)で戻る
「UINT」ならば、(32/8)で戻る
「LONG」ならば、(32/8)で戻る
「DWORD」ならば、(32/8)で戻る
「ULONG」ならば、(32/8)で戻る
「LONG_PTR」ならば、(32/8)で戻る
「DWORD_PTR」ならば、(32/8)で戻る
「HWND」ならば、(32/8)で戻る
「LPARAM」ならば、(32/8)で戻る
「WPARAM」ならば、(32/8)で戻る
「COLORREF」ならば、(32/8)で戻る
「PTSTR」ならば、(32/8)で戻る
「PCTSTR」ならば、(32/8)で戻る
「LPTSTR」ならば、(32/8)で戻る
「LPCTSTR」ならば、(32/8)で戻る
「LPVOID」ならば、(32/8)で戻る
「BOOL」ならば、(32/8)で戻る
もし、LEFTB(型,2)=「LP」ならば、4で戻る
もし、LEFTB(型,1)=「P」ならば、4で戻る
もし、LEFTB(型,1)=「H」ならば、4で戻る
「{型} 型は定義されていません」とエラー発生
●関数ポインタ作成(型として)
結果とは変数
結果を関数ポインタとして作成
結果→引数型=型を","で区切る
結果で戻る
関数ポインタ取得用変数とは変数
●関数ポインタ取得(関数名から引数型で)
関数ポインタ取得用変数=引数型として関数ポインタ作成
関数ポインタ取得用変数→初期化(関数ポインタ取得用変数)
実行文とは文字列="関数ポインタ取得用変数→ポケットは~グローバル:{関数名}("
Iとは整数
Iで0から(引数型を","で区切るの配列要素数-1)まで繰り返す
もし、回数>1ならば、実行文に","を追加
実行文に"自身→引数[{I}]"を追加
実行文に")で戻る"を追加
EVAL(実行文)
関数ポインタ取得用変数→イベントは~自身→ポケットで戻る
関数ポインタ取得用変数→ポインタで戻る
●関数ポインタ実行(ポインタ,{配列}引数一覧,引数型,戻値型)
引数型=引数型を「,」で区切る
引数サイズとは配列
引数とは文字列
位置とは整数=1
引数型で反復
引数サイズ[回数-1]=対象の型サイズ取得
引数に(引数サイズの配列合計)を確保
引数一覧で反復
引数の位置にINT(対象)を引数型[回数-1]でバイナリ設定
位置に引数サイズ[回数-1]を直接足す
EXEC_PTR(ポインタ,引数のバイト数,引数,戻値型)で戻る
●GetProcAddress(hModule,lpProcName) =DLL("kernel32.dll",
"DWORD GetProcAddress(
HMODULE hModule, // DLL モジュールのハンドル
LPCSTR lpProcName // 関数名
)")
●GetModuleHandle(lpModuleName) =DLL("kernel32.dll",
"HMODULE GetModuleHandleA(
LPCTSTR lpModuleName // モジュール名
)")
●MoveMemory(Destination,Source,Length) =DLL("kernel32.dll",
"VOID RtlMoveMemory (
PVOID Destination, // 移動先
VOID *Source, // 移動したいブロック
SIZE_T Length // 移動したいブロックのサイズ
)")
!変数宣言は不要
*例1: マルチスレッド
ポインタ=「MyThreadProc」から「LPRAM」で関数ポインタ取得
スレッド識別子とは整数
CreateThread(0,0,ポインタ,回数,0,POINTER(スレッド識別子))
「ユーザーを待機している最中に...」という
●MyThreadProc(lpParameter)
100回
母艦=「他の処理を実行することができます - 今の時間:{今}」
1秒待つ
●CreateThread(lpThreadAttributes,dwStackSize,lpStartAddress,lpParameter,dwCreationFlags,lpThreadId) =DLL("kernel32.dll",
"HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // セキュリティ記述子
DWORD dwStackSize, // 初期のスタックサイズ
LPTHREAD_START_ROUTINE lpStartAddress, // スレッドの機能
LPVOID lpParameter, // スレッドの引数
DWORD dwCreationFlags, // 作成オプション
LPDWORD lpThreadId // スレッド識別子
)")
*例2: 窓列挙
ログとはメモ
そのレイアウトは「全体」
ポインタ="MyEnumWindowsProc"から"HWND,LPARAM"で関数ポインタ取得
EnumWindows(ポインタ,0)
●MyEnumWindowsProc(hwnd,lParam)
バッファとは文字列
バッファに260を確保
GetWindowText(hwnd,POINTER(バッファ),260)
タイトルとは文字列=LEFTB(バッファ,それ)
ログのテキスト=ログのテキスト&"{hwnd},{タイトル}{~}"
1で戻る
●EnumWindows(lpEnumFunc,lParam) =DLL("user32.dll",
"BOOL EnumWindows(
WNDENUMPROC *lpEnumFunc, // コールバック関数
LPARAM lParam // アプリケーション定義の値
)")
●GetWindowText(hWnd,lpString,nMaxCount) =DLL("user32.dll",
"int GetWindowTextA(
HWND hWnd, // ウィンドウまたはコントロールのハンドル
LPTSTR lpString, // テキストバッファ
int nMaxCount // コピーする最大文字数
)")
----
総合:&counter()
今日:&counter(today)人
昨日:&counter(yesterday)人
#comment()
*情報
作者名:YouTubeダウンロードし放題
引用元:[[なでしこプログラム掲示板「代用関数ポインタ」>http://nade.jp-pro.net/bbs/bbs3/cbbs.cgi?mode=al2&number=5747&no=0&KLOG=6]]&br()[[なでしこライブラリ「関数ポインタ」>http://www26.atwiki.jp/isoroku_be/pages/67.html]]
*概要
関数ポインタが最新のなでしこで使えない..って人が多かったので不具合を直しました。
これを使えばなでしこで
-マルチスレッド
-フォームをWinAPIレベルから作成してメッセージループを回す
-非同期な通信
-重い処理の非同期実行
などの高度な処理を実現できます
*[[ソースダウンロード>http://www26.atwiki.jp/isoroku_be?cmd=upload&act=open&pageid=189&file=%E9%96%A2%E6%95%B0%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF+2.05.nako]]
*[[サンプル集ダウンロード>http://www26.atwiki.jp/isoroku_be?cmd=upload&act=open&pageid=189&file=%E9%96%A2%E6%95%B0%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF+2.05.zip]]
*変更点
-ver2.10
+●関数ポインタ作成 でイベントを事前にEVALで登録するように修正(高速化)
-ver2.05
+使いやすいように関数命令を追加&br()●関数ポインタ取得&br()●関数ポインタ取得&br()●関数ポインタ実行
+2個以上関数ポインタを作成した場合のアドレス重複エラーを修正
+関数内での宣言をサポート
+わざわざVirtualAllocでメモリを確保する理由もなく、メモリを解放し忘れる人が多いのでなでしこの「確保」命令に置換&br()(追記: やっぱり実行アクセスの有無が違うらしい... でも実行アクセスがなくてもなぜか実行できるので保留。)
-ver1.01
+グローバルからアクセスできるように
+引数の型を指定できるように
*本体
!変数宣言は必要
!NAKO_GROUP_EXEC=GetProcAddress(GetModuleHandle("dnako.dll"),"nako_group_exec");
!関数ポインタ既定イベント名 = "前処理";
■関数ポインタ
・{イベント}イベント
・{整数}ポインタ
・{配列}引数
・{配列}引数型
・ポケット
・タグ
・{非公開}初期化({グループ}参照)~
型サイズ=空
引数型で反復
対象の型サイズ取得を型サイズに配列追加
バッファに64を確保
バッファの01に$55を「BYTE」でバイナリ設定
バッファの02に$EC8Bを「SHORT」でバイナリ設定
バッファの04に$BAを「BYTE」でバイナリ設定
バッファの05にPOINTER(スタック)を「int」でバイナリ設定
バッファの09に$2A89を「SHORT」でバイナリ設定
バッファの11に$68を「BYTE」でバイナリ設定
バッファの12にPOINTER(関数ポインタ既定イベント名)を「int」でバイナリ設定
バッファの16に$68を「BYTE」でバイナリ設定
バッファの17にADDR(参照)を「int」でバイナリ設定
バッファの21に$B8を「BYTE」でバイナリ設定
バッファの22にNAKO_GROUP_EXECを「int」でバイナリ設定
バッファの26に$D0FFを「SHORT」でバイナリ設定
バッファの28に$058Bを「SHORT」でバイナリ設定
バッファの30にPOINTER(返り値)を「int」でバイナリ設定
バッファの34に$5Dを「BYTE」でバイナリ設定
バッファの35に$C2を「BYTE」でバイナリ設定
バッファの36に(型サイズの配列合計)を「SHORT」でバイナリ設定
ポインタ=POINTER(バッファ)
・{非公開}前処理~
TMPとは整数
TMP=スタック+4
(引数型の配列要素数)回
引数[回数-1]=0
TMP=TMP+型サイズ[回数-1]
MoveMemory(POINTER(引数[回数-1]),TMP,型サイズ[回数-1])
返り値=イベント
・{文字列}バッファ
・{整数}スタック
・{配列}型サイズ
・{整数}返り値
●型サイズ取得(型の)
型=型を大文字変換
型で条件分岐
「CHAR」ならば、(8/8)で戻る
「BYTE」ならば、(8/8)で戻る
「WCHAR」ならば、(16/8)で戻る
「SHORT」ならば、(16/8)で戻る
「WORD」ならば、(16/8)で戻る
「INT」ならば、(32/8)で戻る
「UINT」ならば、(32/8)で戻る
「LONG」ならば、(32/8)で戻る
「DWORD」ならば、(32/8)で戻る
「ULONG」ならば、(32/8)で戻る
「LONG_PTR」ならば、(32/8)で戻る
「DWORD_PTR」ならば、(32/8)で戻る
「HWND」ならば、(32/8)で戻る
「LPARAM」ならば、(32/8)で戻る
「WPARAM」ならば、(32/8)で戻る
「COLORREF」ならば、(32/8)で戻る
「PTSTR」ならば、(32/8)で戻る
「PCTSTR」ならば、(32/8)で戻る
「LPTSTR」ならば、(32/8)で戻る
「LPCTSTR」ならば、(32/8)で戻る
「LPVOID」ならば、(32/8)で戻る
「BOOL」ならば、(32/8)で戻る
もし、LEFTB(型,2)=「LP」ならば、4で戻る
もし、LEFTB(型,1)=「P」ならば、4で戻る
もし、LEFTB(型,1)=「H」ならば、4で戻る
「{型} 型は定義されていません」とエラー発生
●関数ポインタ作成(型として)
結果とは変数
結果を関数ポインタとして作成
結果→引数型=型を","で区切る
結果で戻る
関数ポインタ取得用変数とは変数
●関数ポインタ取得(関数名から引数型で)
関数ポインタ取得用変数=引数型として関数ポインタ作成
関数ポインタ取得用変数→初期化(関数ポインタ取得用変数)
実行文とは文字列="関数ポインタ取得用変数→ポケットは~グローバル:{関数名}("
Iとは整数
Iで0から(引数型を","で区切るの配列要素数-1)まで繰り返す
もし、回数>1ならば、実行文に","を追加
実行文に"自身→引数[{I}]"を追加
実行文に")で戻る"を追加
EVAL(実行文)
関数ポインタ取得用変数→イベントは~自身→ポケットで戻る
関数ポインタ取得用変数→ポインタで戻る
●関数ポインタ実行(ポインタ,{配列}引数一覧,引数型,戻値型)
引数型=引数型を「,」で区切る
引数サイズとは配列
引数とは文字列
位置とは整数=1
引数型で反復
引数サイズ[回数-1]=対象の型サイズ取得
引数に(引数サイズの配列合計)を確保
引数一覧で反復
引数の位置にINT(対象)を引数型[回数-1]でバイナリ設定
位置に引数サイズ[回数-1]を直接足す
EXEC_PTR(ポインタ,引数のバイト数,引数,戻値型)で戻る
●GetProcAddress(hModule,lpProcName) =DLL("kernel32.dll",
"DWORD GetProcAddress(
HMODULE hModule, // DLL モジュールのハンドル
LPCSTR lpProcName // 関数名
)")
●GetModuleHandle(lpModuleName) =DLL("kernel32.dll",
"HMODULE GetModuleHandleA(
LPCTSTR lpModuleName // モジュール名
)")
●MoveMemory(Destination,Source,Length) =DLL("kernel32.dll",
"VOID RtlMoveMemory (
PVOID Destination, // 移動先
VOID *Source, // 移動したいブロック
SIZE_T Length // 移動したいブロックのサイズ
)")
!変数宣言は不要
*例1: マルチスレッド
ポインタ=「MyThreadProc」から「LPRAM」で関数ポインタ取得
スレッド識別子とは整数
CreateThread(0,0,ポインタ,回数,0,POINTER(スレッド識別子))
「ユーザーを待機している最中に...」という
●MyThreadProc(lpParameter)
100回
母艦=「他の処理を実行することができます - 今の時間:{今}」
1秒待つ
●CreateThread(lpThreadAttributes,dwStackSize,lpStartAddress,lpParameter,dwCreationFlags,lpThreadId) =DLL("kernel32.dll",
"HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // セキュリティ記述子
DWORD dwStackSize, // 初期のスタックサイズ
LPTHREAD_START_ROUTINE lpStartAddress, // スレッドの機能
LPVOID lpParameter, // スレッドの引数
DWORD dwCreationFlags, // 作成オプション
LPDWORD lpThreadId // スレッド識別子
)")
*例2: 窓列挙
ログとはメモ
そのレイアウトは「全体」
ポインタ="MyEnumWindowsProc"から"HWND,LPARAM"で関数ポインタ取得
EnumWindows(ポインタ,0)
●MyEnumWindowsProc(hwnd,lParam)
バッファとは文字列
バッファに260を確保
GetWindowText(hwnd,POINTER(バッファ),260)
タイトルとは文字列=LEFTB(バッファ,それ)
ログのテキスト=ログのテキスト&"{hwnd},{タイトル}{~}"
1で戻る
●EnumWindows(lpEnumFunc,lParam) =DLL("user32.dll",
"BOOL EnumWindows(
WNDENUMPROC *lpEnumFunc, // コールバック関数
LPARAM lParam // アプリケーション定義の値
)")
●GetWindowText(hWnd,lpString,nMaxCount) =DLL("user32.dll",
"int GetWindowTextA(
HWND hWnd, // ウィンドウまたはコントロールのハンドル
LPTSTR lpString, // テキストバッファ
int nMaxCount // コピーする最大文字数
)")
----
総合:&counter()
今日:&counter(today)人
昨日:&counter(yesterday)人
#comment()