Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
PHPからWin32APIをいじってみた
Search
taiko19xx
September 24, 2016
Programming
1.8k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
PHPからWin32APIをいじってみた
2016/09/24の「第一回PHP勉強会@仙台(仮)」で発表した資料です。
taiko19xx
September 24, 2016
More Decks by taiko19xx
See All by taiko19xx
Bedrockで遊ぼう! 短期間で色々開発してみた
taiko19xx
1
200
Incident Managerでインシデント発生時のエスカレーションを自動化する
taiko19xx
0
300
LambdaカスタムランタイムでPHPでもサーバーレス!
taiko19xx
0
100
IoTっぽいアプリをk3s+Raspberry Piで実行する
taiko19xx
0
370
ハニーポットから見たWebサーバへの攻撃
taiko19xx
0
3k
PHPなプロダクトをAmazon ECSで開発運用してる話
taiko19xx
0
1.4k
RaspberryPi+AWSでIoT(っぽ い)GPSロガーを作ってみた
taiko19xx
0
1.7k
Other Decks in Programming
See All in Programming
graphql-ruby を Spinel で速くしようとした話
mtsmfm
0
140
선언형 햅틱 라이브러리 진동을 소개합니다
l2hyunwoo
1
300
小さなアプリを作って公開するまで
onozaty
0
150
TanStack Vue Query と Pinia Colada から学ぶ非同期状態の型設計
aoshi
0
630
Kotlinize Is Not Just Converting to Kotlin
chigichan24
1
220
Apple Intelligenceとオンデバイス時代の到来
yahir0
0
230
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
240
SODA - FACT BOOK(EN)
sodainc
1
220
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
4
3.8k
私なりのハーネスエンジニアリング ~独自の言語処理系の開発を通して~
seosoft
0
190
プロジェクトコードをキレイキレイしよう!暗黙的な参照を読み解く静的解析
ostk0069
0
210
AI-Powered Domain-Driven Design
ziobrando
0
420
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
340
58k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
8.2k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
760
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
740
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
470
Raft: Consensus for Rubyists
vanstee
143
7.9k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
480
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.2k
How to Ace a Technical Interview
jacobian
280
24k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
How to build a perfect <img>
jonoalderson
1
6.2k
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