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
130
Incident Managerでインシデント発生時のエスカレーションを自動化する
taiko19xx
0
240
LambdaカスタムランタイムでPHPでもサーバーレス!
taiko19xx
0
76
IoTっぽいアプリをk3s+Raspberry Piで実行する
taiko19xx
0
330
ハニーポットから見たWebサーバへの攻撃
taiko19xx
0
2.9k
PHPなプロダクトをAmazon ECSで開発運用してる話
taiko19xx
0
1.2k
RaspberryPi+AWSでIoT(っぽ い)GPSロガーを作ってみた
taiko19xx
0
1.6k
Other Decks in Programming
See All in Programming
ruby.wasmで多人数リアルタイム通信ゲームを作ろう
lnit
3
360
Is Xcode slowly dying out in 2025?
uetyo
1
250
LINEヤフー データグループ紹介
lycorp_recruit_jp
0
1.8k
datadog dash 2025 LLM observability for reliability and stability
ivry_presentationmaterials
0
440
今ならAmazon ECSのサービス間通信をどう選ぶか / Selection of ECS Interservice Communication 2025
tkikuc
21
3.8k
Team topologies and the microservice architecture: a synergistic relationship
cer
PRO
0
1.2k
PHPで始める振る舞い駆動開発(Behaviour-Driven Development)
ohmori_yusuke
2
250
AIプログラマーDevinは PHPerの夢を見るか?
shinyasaita
1
190
PHPでWebSocketサーバーを実装しよう2025
kubotak
0
260
GraphRAGの仕組みまるわかり
tosuri13
8
520
明示と暗黙 ー PHPとGoの インターフェイスの違いを知る
shimabox
2
470
データの民主化を支える、透明性のあるデータ利活用への挑戦 2025-06-25 Database Engineering Meetup#7
y_ken
0
340
Featured
See All Featured
Agile that works and the tools we love
rasmusluckow
329
21k
Making Projects Easy
brettharned
116
6.3k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
357
30k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.5k
A better future with KSS
kneath
239
17k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.5k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
657
60k
Why You Should Never Use an ORM
jnunemaker
PRO
58
9.4k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Producing Creativity
orderedlist
PRO
346
40k
Into the Great Unknown - MozCon
thekraken
39
1.9k
Thoughts on Productivity
jonyablonski
69
4.7k
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