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
140
Incident Managerでインシデント発生時のエスカレーションを自動化する
taiko19xx
0
250
LambdaカスタムランタイムでPHPでもサーバーレス!
taiko19xx
0
79
IoTっぽいアプリをk3s+Raspberry Piで実行する
taiko19xx
0
340
ハニーポットから見たWebサーバへの攻撃
taiko19xx
0
2.9k
PHPなプロダクトをAmazon ECSで開発運用してる話
taiko19xx
0
1.3k
RaspberryPi+AWSでIoT(っぽ い)GPSロガーを作ってみた
taiko19xx
0
1.6k
Other Decks in Programming
See All in Programming
Introducing ReActionView: A new ActionView-Compatible ERB Engine @ Kaigi on Rails 2025, Tokyo, Japan
marcoroth
3
960
CSC509 Lecture 01
javiergs
PRO
1
440
2分台で1500examples完走!爆速CIを支える環境構築術 - Kaigi on Rails 2025
falcon8823
3
3.4k
Pythonスレッドとは結局何なのか? CPython実装から見るNoGIL時代の変化
curekoshimizu
5
1.6k
技術的負債の正体を知って向き合う / Facing Technical Debt
irof
0
120
Breaking Up with Big ViewModels — Without Breaking Your Architecture (droidcon Berlin 2025)
steliosf
PRO
1
350
アメ車でサンノゼを走ってきたよ!
s_shimotori
0
210
CSC509 Lecture 05
javiergs
PRO
0
300
どの様にAIエージェントと 協業すべきだったのか?
takefumiyoshii
2
620
タスクの特性や不確実性に応じた最適な作業スタイルの選択(ペアプロ・モブプロ・ソロプロ)と実践 / Optimal Work Style Selection: Pair, Mob, or Solo Programming.
honyanya
3
150
overlayPreferenceValue で実現する ピュア SwiftUI な AdMob ネイティブ広告
uhucream
0
170
CSC305 Lecture 02
javiergs
PRO
1
260
Featured
See All Featured
Embracing the Ebb and Flow
colly
88
4.8k
Optimizing for Happiness
mojombo
379
70k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.2k
KATA
mclloyd
32
15k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
23
1.5k
Build The Right Thing And Hit Your Dates
maggiecrowley
37
2.9k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Practical Orchestrator
shlominoach
190
11k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
9
850
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
54
3k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.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