php extensionへの既存C/C++ライブラリ取り込み
最近php extensionを自作する機会が出たので、いろいろと検索しても情報が少なかったのもあってメモ
extensionの作成helloworld的なページ
http://dsas.blog.klab.org/archives/50777398.html
http://dsas.blog.klab.org/archives/50782987.html
http://dsas.blog.klab.org/archives/50903613.html
CPPを含む場合の対応について
http://devzone.zend.com/1435/wrapping-c-classes-in-a-php-extension/
その他参考にしたページ
http://pwiki.awm.jp/~yoya/?PHP/ext#classconst
http://oshiete.goo.ne.jp/qa/7151754.html
http://d.hatena.ne.jp/rikunora2/touch/20100802/1280731016
で、やろうとしたことは既存の静的ライブラリ(.aファイル)をphpで呼び出せるようにラッパーすること。
結論から言うと、PHP extensionの作成でライブラリをリンクするときは、shared objectでないといけないらしい。
静的ライブラリとしてコンパイルした物は使えない。
エラーとしてはこういうものがmake時に出力される模様。
/usr/bin/ld: /path/to/hoge.a(hoge.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/path/to/hoge.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [huga.la] エラー 1
「-fPIC」というオプションをつけろということらしい。
for文のループ方法について
まとめサイトを巡ってたら気になるコメントがあったので試してみたメモ。
http://blog.livedoor.jp/itsoku/archives/41660022.html
このコメント73の「デクリメントのほうが演算コストが云々・・・」の部分。
このあとすぐに「マシン語レベルだと変わらない」と判断されてたけど、実際どうなのか確かめてみようかと。
コンパイルとかも面倒だったんでとりあえずnode.jsで。
var MAX = 100000000; var start = new Date().getTime(); for(var i = 0; i < MAX; i++){} // (1) var end = new Date().getTime(); console.log("for(var i = 0; i < MAX; i++){} : " + (end - start) + "(msec)"); var start = new Date().getTime(); for(var i = MAX; i; i--){} // (2) var end = new Date().getTime(); console.log("for(var i = MAX; i; i--){} : " + (end - start) + "(msec)");
やってみた結果、前者は96msくらいで、後者が126msくらい。
後者のほうが若干遅くなる模様。
他の言語でやってみた場合どうなるか気になるなあ。
11/03 00:03追記
C言語で同様のコードを試してみたら(1)が230ms、(2)が210msだった。
i < MAXの比較処理分の差が出たのかなあ。
findAndModifyについて
MongoDBのクエリの一つ、findAndModify
便利なクエリなんだけど、制約も多いのでメモ。
MongoDBのドキュメントにも載っていることなので、詳しくはそちらを。
- 更新は1ドキュメントのみ
要はfindOneして見つかったデータのみ更新されると思えば良い。
こんなかんじのクエリを実行しても、更新されるのは最初の1件のみ。
db.test.findAndModify({query : {hoge:{$in:["a", "b", "c"]}}, update : {$set:{foo:100}}})
- shard keyを含まないクエリはエラーになる
これは知らずにやってしまうと結構問題になったりするかも。ローカルの環境ではshardingなんてやらないことがほとんどだと思うので。
sharding構成をとっている場合、検索のキーにはshard keyを含む必要がある。
これを満たしていないと問答無用でエラーにる。
// shard key : "hoge"の場合 // これはOK db.test.findAndModify({query : {hoge:"a"}, update : {$set:{foo:100}}}) // これはアウト db.test.findAndModify({query : {piyo:"a"}, update : {$set:{foo:100}}})
オブジェクトの代入
JavascriptのObjectやArrayは代入すると参照コピーになってしまう。
つまりこういうことをやってしまうと
var hoge = {a : 100}; var piyo = hoge; piyo.a = 1024; console.log(hoge.a); // 1024
hogeとpiyoは全く同じものなので、piyoだけ書き換える、ということができない。
中身の値だけコピーしたい場合はこうすればいい。
var piyo = JSON.parse(JSON.stringify(hoge));
中身のfunctionもまるっとディープコピーする場合は
ちゃんと再帰的に走査してコピーする関数を作らないといけない。
ちゃんと代入されてるはずなのに・・・?と小一時間ほどハマっってしまった。
調べて初めて知ったよ。
俯瞰の風景と初めての3D
土曜日に空の境界 俯瞰風景3Dを見てきた。
俯瞰風景を映画館で見てから6年もたってるんだなあ・・・
ゼロカフェは海魔が意外と可愛かったw
10分程度ながら面白かったんで、別のお話を見てみたいと思った。
本編の方はすでに見たことあるとはいえ、相変わらずのクオリティだった。
ただ、3Dの映画に関しては今回が初だったんだけど、正直「こんなもんかー」というのが感想だった。
もともと3Dのために作られた作品じゃないし、仕方ないのかな。
飛び降りるところとか、雰囲気は良くなってた気はするんだけど。
見終わったあとは、デレた式の破壊力を再確認しました。
実は上映中、3Dメガネの方の構造に興味が行ってたりする。
電池を入れるような部分があったし、シャッター方式なのかなーと思って帰ってから調べたら、やっぱりシャッター方式だった。
シャッター方式ってもっとごついメガネなのかなと思ってたから、見た目シンプルで驚いた。