Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
PHPからWin32APIをいじってみた
Search
taiko19xx
September 24, 2016
Programming
0
1.7k
PHPからWin32APIをいじってみた
2016/09/24の「第一回PHP勉強会@仙台(仮)」で発表した資料です。
taiko19xx
September 24, 2016
Tweet
Share
More Decks by taiko19xx
See All by taiko19xx
Bedrockで遊ぼう! 短期間で色々開発してみた
taiko19xx
1
120
Incident Managerでインシデント発生時のエスカレーションを自動化する
taiko19xx
0
220
LambdaカスタムランタイムでPHPでもサーバーレス!
taiko19xx
0
75
IoTっぽいアプリをk3s+Raspberry Piで実行する
taiko19xx
0
320
ハニーポットから見たWebサーバへの攻撃
taiko19xx
0
2.8k
PHPなプロダクトをAmazon ECSで開発運用してる話
taiko19xx
0
1.2k
RaspberryPi+AWSでIoT(っぽ い)GPSロガーを作ってみた
taiko19xx
0
1.5k
Other Decks in Programming
See All in Programming
API for docs
soutaro
3
1.5k
Boost Your Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
570
Bedrock×MCPで社内ブログ執筆文化を育てたい!
har1101
6
1.3k
The Implementations of Advanced LR Parser Algorithm
junk0612
1
920
On-the-fly Suggestions of Rewriting Method Deprecations
ohbarye
1
4.3k
Instrumentsを使用した アプリのパフォーマンス向上方法
hinakko
0
210
エンジニアが挑む、限界までの越境
nealle
1
290
fieldalignmentから見るGoの構造体
kuro_kurorrr
0
120
ComposeでのPicture in Picture
takathemax
0
130
Ruby on Railroad: The Power of Visualizing CFG
ydah
0
270
AIコーディングエージェントを 「使いこなす」ための実践知と現在地 in ログラス / How to Use AI Coding Agent in Loglass
rkaga
4
1.1k
新しいPHP拡張モジュールインストール方法「PHP Installer for Extensions (PIE)」を使ってみよう!
cocoeyes02
0
440
Featured
See All Featured
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.5k
Site-Speed That Sticks
csswizardry
6
520
A better future with KSS
kneath
239
17k
Rails Girls Zürich Keynote
gr2m
94
13k
Typedesign – Prime Four
hannesfritz
41
2.6k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
14
1.4k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
41
2.3k
Stop Working from a Prison Cell
hatefulcrawdad
268
20k
The World Runs on Bad Software
bkeepers
PRO
68
11k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.6k
Bash Introduction
62gerente
611
210k
Transcript
PHPからWin32APIを いじってみた 2016/09/24第一回PHP勉強会@仙台(仮) Taiko19xx / 木村俊彦
こんにちは • 木村俊彦 • Twitter / GitHub : taiko19xx •
株式会社SRIA エンジニア • 普段はもちろんPHP • たまにスマホアプリとかもやりたい • 趣味は旅行とカメラとバイク • 最近は大洗とか北海道へ
早速ですが アンケート
自宅か会社で Windowsを 使ってる方は?
自宅も会社も Mac / *nixの方!
None
今回の話はタイトルの通り、 「PHPからWindowsのAPIをいじる」 という話です…
Win32APIとは?
Win32APIとは Windows API(ウィンドウズ エーピーアイ)とは、 Microsoft WindowsのAPIのことである。 特に32ビットプロセッサで動作するWindows 95 以降やWindows NTで利用できるものはWin32
APIと呼ばれる。また、それらのWindowsにおけ るWin32 APIの実装をWin32と呼ぶ。 (https://ja.wikipedia.org/wiki/Windows_APIより)
None
つまり • 意味合いとしてはよくご存じの「API」と同じで、Windowsが 提供している各機能へのアクセス窓口 • 「各機能」の範囲は幅広く… • ファイルの読み書き • ウィンドウの表示
• GUIの制御 などなど • 例えば、ファイルの読み書きをする関数(ex. fopen/fwrite)は Win32APIを裏で呼び出している • PHPから呼べない機能を使いたい場合は直接呼ぶしかない
直接呼べるのか? • Windows APIに属する各APIは、主にDLLからの関数または COMインターフェイスとして機能を公開している。 (Wikipediaより) • そのため、言語や環境を問わず、DLLを読んだりCOMへアクセ スする事で自由に呼び出す事ができます •
PHPにはCOMを使えるようにするcom_dotnet拡張があるので、 これを利用します
None
利用準備
php_com_dotnet.dllの有効化 • 普段からバリバリ使ってる方にはお馴染み • 標準で添付されていますが、5.3.15/5.4.5以降は手動で有効に する必要あり • php.iniに「extension=php_com_dotnet.dll」を追記するだけ • 「php
–i」を実行して、com_dotnetが確認できればOK
None
None
DynamicWrapperの導入 • com_dotnetからWin32APIを呼び出そうとすると少し大変なの で、DynamicWrapperというWin32APIのラッパーも導入 • http://www.borncity.com/web/WSHBazaar1/WSHDynaCall.htm • dynawrapnt.zipをダウンロードして解凍し、下記コマンドでシ ステムにDLLを登録 •
regsvr32.exe <path>dynwrap.dll • PHP -> com_dotnet -> DynamicWrapper -> Win32APIという 若干遠回りな呼び出しになるが、これで扱えるように
None
ここで注意
PHPは 32bit版(x86)を 使用しましょう!
何故か • DynamicWrapperが32bitのDLLのため • 32bitのDLLは64bitのアプリケーションからは呼べない制約がある • その逆も然り • DLLを調整すれば64bitからでも呼べるようになる、らしい •
これに気付くまで2~3時間ハマってました…
None
動かしてみる
今回表示するもの
やってみましょう • メッセージボックスを表示するだけ 1. com_dotnetでDynamicWrapperを呼び出し 2. 利用したいWin32APIを内包しているDLLと関数名をRegist()に渡し、 呼び出しの準備をする • 今回はMessageBox()関数を呼び出します
• https://msdn.microsoft.com/ja-jp/library/cc410914.aspx 3. 実際に関数を呼び出す
Register() • 利用したい関数とDLLを読み込む • 引数はこんな感じ • 呼び出すDLL名(必須) • 呼び出す関数名(必須) •
関数に渡す引数の型フラグ(オプション、i=に続けて指定) • 呼出規約の種類フラグ(オプション、f=に続けて指定) • 返り値の型フラグ(オプション、 r=に続けて指定)
引数/返り値の型 指定するフラグ 型名 a IDispatch c unsigined char d 8byte
real f 4byte real k IUnknown h handle (4bytes) l long (4bytes) p pointer s string t short (2bytes) u unsigined int w wide string
MessageBoxの場合 • MessageBox(HWND, LPCSTR, LPCSTR, UNIT) • 100%一致する訳ではないので、ある程度予測して当てはめる • LPCSTR(const
char*)に該当するのは無いので、stringを割り当てる • HWND = h, LPCSTR = s, UNIT = u とする • つまり、「i = hssu」となる
呼出規約 プログラミングにおける呼出規約(よびだしきやく)ないし呼出 慣例(よびだしかんれい)はサブルーチンを呼び出す際の標準的 な手法を指す。サブルーチンにデータを渡し、戻るべきアドレス (リターンアドレス)を記録し、サブルーチンからデータを受け 取るための規則である。一つのプログラムでは、(複数の言語処 理系を用いて記述する場合も)同一の呼出規約を守る必要がある。 さまざまな呼出規約があり、引数のコールスタック(以下単にス タックと呼ぶ)への格納法、サブルーチンにデータを渡す方法、 サブルーチンからの復帰法、名前修飾が異なる。
(https://ja.wikipedia.org/wiki/%E5%91%BC%E5%87%BA%E8%A6%8F%E7%B4%84より)
呼出規約の種類 指定するフラグ 内容 m Microsoft (bと排他的) b Borland (mと排他的) s
_stdcall (cと排他的) c _cdeel (sと排他的) 4 4 byte real value returned in ST(8と排他的) 8 8 byte real value returned in ST(4と排他的) • デフォルトは「f=ms」 • そのままでも問題なく利用できるので、特に指定のない場合は 省略してもOK
関数の呼出 • Register()で登録した関数は、上記のように呼び出す • なので、1回登録すればその後は複数回呼び出せる • 引数によってはnullを指定できる場合があるので、マニュアル を参照のこと • 呼出時の型は、PHP側も合わせる必要がある
日本語を渡す
日本語を渡す
日本語を渡す • 普通に何もせずに渡してしまうとエラーになる • mb_convert_encoding()でSJISやSJIS-winに変換すればOK
返り値 • 返り値のある関数の場合、PHPでその返り値を受け取れます • Registerで「r=」のフラグを利用して、引数と同じように型を 推測して登録しておく必要があります • MessageBox()の場合、押したボタンによって数値が返ってく るので、「r=u」を指定すればOK
返り値
まとめ
まとめ • PHPからWin32APIを扱うにはそれなりの準備が必要 • 環境依存もあるし • 使いこなすのであれば、下記が必要そう • MSDNなどのドキュメントを隅から隅まで読む時間 •
Win32APIについての理解 • 準備や調査に対してのリターンが大きくないので、積極的に使 いこなす必要はあまりなさそう • PHPとは全然違う分野の理解も深まるので、「最近新しい知識 仕入れてないな」という方は試してみるといいかもしれません • 温故知新
雑感 • 調査前に考慮していたよりも手軽に扱えた • 個人の意見です • 本格的なGUIアプリケーションは厳しそう • やれなくはなさそうだが… •
スクリプトを利用した作業を補助するくらいであれば手軽 • 処理が終わったらアラートを出すとか • エラーを出すとか • 返り値で分岐もできるので、特定の選択肢の場合は再度走らせるとか • 少し勉強したCとかC++の知識が少し役立った瞬間でした
参考 • PHP: COM関数 - Manual • http://php.net/manual/ja/ref.com.php • PHPでWin32APIを呼ぶ(Windows)
- Qiita • http://qiita.com/joh/items/9f54c6876e356c51157 • An Automation Object for Dynamic DLL Calls | Dr Dobb's • http://www.drdobbs.com/windows/an-automation-object-for- dynamic-dll-cal/210200078 • Born's Windows Scripting Host • http://www.borncity.com/web/WSHBazaar1/WSHDynaCall.htm
参考 • MessageBox 関数 (MSDN) • https://msdn.microsoft.com/ja-jp/library/cc410914.aspx • No.18 msgBoxのパラメータ(早見表)
• http://www.niji.or.jp/home/toru/notes/18.html