■関数ポインタ改

※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

情報

概要

関数ポインタが最新のなでしこで使えない..って人が多かったので不具合を直しました。
これを使えばなでしこで
  • マルチスレッド
  • フォームをWinAPIレベルから作成してメッセージループを回す
  • 非同期な通信
  • 重い処理の非同期実行
などの高度な処理を実現できます

ソースダウンロード

サンプル集ダウンロード

変更点

  • ver2.10
  1. ●関数ポインタ作成 でイベントを事前にEVALで登録するように修正(高速化)
  • ver2.05
  1. 使いやすいように関数命令を追加
    ●関数ポインタ取得
    ●関数ポインタ取得
    ●関数ポインタ実行
  2. 2個以上関数ポインタを作成した場合のアドレス重複エラーを修正
  3. 関数内での宣言をサポート
  4. わざわざVirtualAllocでメモリを確保する理由もなく、メモリを解放し忘れる人が多いのでなでしこの「確保」命令に置換
    (追記: やっぱり実行アクセスの有無が違うらしい... でも実行アクセスがなくてもなぜか実行できるので保留。)
  • ver1.01
  1. グローバルからアクセスできるように
  2. 引数の型を指定できるように

本体

!変数宣言は必要
!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     // コピーする最大文字数
)")

総合: -
今日: -
昨日: -
名前:
コメント:
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。