2007/10/01

はてな
nayoyaグループ - naoyaの日記 - Gearmanのやつ#2
clouderさんは結局、MSG_WAITALLを使う方法を取られたようですね。個人な趣味としてはあまりMSG_WAITALLは使わないほうなので、きっと私の場合はループを回すかな。
理由は大した事ではなく、サーバ側で「Content-Length」を出力し、そのContent-Length数分データを送信するようなCGIを書いた場合、バグで「Content-Length」分満たない内に落ちてしまった場合に、クライアントの受信がMSG_WAITALLだとバッファ全部破棄されてしまいエラーハンドリングし辛いからです。
(※たとえばどこまで受信したかが分からないとか...)
今日は本題から外れますが、上記リンクの中にも出てきたソケットディスクリプタから「fdopen」する処理をWindowsではどう書くかをご紹介。

続きを読む...


2007/09/28

はてな

ローカルDBやメモリDBとして使えるSQLiteは、開発者にとってかなり有用なツールです。 私はよく「あーーーあのSQLどう書こう」なんて悩む時にSQLiteのshell版を使います。今日はそのWin32 SQLite3のshell版sqlite3.exeの作り方をご紹介。

まず、ダウンロードページから
sqlite-3_5_0.zip
というファイルをダウンロードします。
次に、ソースツリー内の「src」ディレクトリに移動し、以下のMakefileを置きます。
.SUFFIXES: .c .obj

all : sqlite3.exe

sqlite3.exe :  alter.obj analyze.obj attach.obj auth.obj btree.obj build.obj callback.obj complete.obj date.obj delete.obj expr.obj func.obj hash.obj insert.obj legacy.obj loadext.obj main.obj opcodes.obj os.obj os_os2.obj os_unix.obj os_win.obj pager.obj parse.obj pragma.obj prepare.obj printf.obj random.obj select.obj shell.obj table.obj tokenize.obj trigger.obj update.obj utf.obj util.obj vacuum.obj vdbe.obj vdbeblob.obj vdbeapi.obj vdbeaux.obj vdbefifo.obj vdbemem.obj vtab.obj where.obj mutex.obj mem1.obj malloc.obj
    cl /Fesqlite3.exe alter.obj analyze.obj attach.obj auth.obj btree.obj build.obj callback.obj complete.obj date.obj delete.obj expr.obj func.obj hash.obj insert.obj legacy.obj loadext.obj main.obj opcodes.obj os.obj os_os2.obj os_unix.obj os_win.obj pager.obj parse.obj pragma.obj prepare.obj printf.obj random.obj select.obj shell.obj table.obj tokenize.obj trigger.obj update.obj utf.obj util.obj vacuum.obj vdbe.obj vdbeblob.obj vdbeapi.obj vdbeaux.obj vdbefifo.obj vdbemem.obj vtab.obj where.obj mutex.obj mem1.obj malloc.obj

.c.obj :
    cl /c /DSQLITE_THREADSAFE=0 $<
後は、Visual Studioのコンパイラにパスが通ってるならば「nmake」でコンパイルします。 なおSQLiteは、内部処理がUTF-8でやり取りされており、Win32版の場合はNTかどうかでCreateFileA/CreateFileW等、ワイド文字APIの呼び方を変えています。
しかし、コマンドライン引数には対応出来ておらず
C:¥> sqlite3.exe データベース.db
なんて事すると、エラーが発生します。ちなみにNTでない場合には変換無しにCreateFileAを使いますから問題なく動きます。
これって、コマンドラインをUTF-8にすれば動くんだろうけど
C:¥> chcp 65001
やってUTF-8にしても文字は化けるし、IME動かないし意味無いですよね。
適当に
--- os_win.c.orig   Mon Sep 03 22:39:38 2007
+++ os_win.c    Fri Sep 28 22:17:50 2007
@@ -137,6 +137,8 @@
 # define isNT()  (1)
 #else
   static int isNT(void){
+    if( GetACP() != CP_UTF8 )
+      return FALSE;
     if( sqlite3_os_type==0 ){
       OSVERSIONINFO sInfo;
       sInfo.dwOSVersionInfoSize = sizeof(sInfo);
こんなパッチ当てて、実行すると日本語のファイル名も扱える様になります。
このEXEをUSBなんかで常備しておくと、いざという時に助けられるかもしれませんね。


2007/06/04

はてな
ショートカット一発検索で生活が変わる を見ていて、普段自分がWindowsで使ってるキーボードショートカットを書いて見る事にする。

ウィンドウ最大化
Alt-Space Alt-X
押し方はAltキーを押しっぱなしで「スペース」、「X」と連続で押す。
元に戻したい場合は「X」の代わりに「R」を押す。
システムのプロパティ
Win-Pause
押し方はWindowsキーを押しながらPauseキー
まれに無限ループするプログラムを書いてしまった時等に、プロセス強制終了したい場合等に使う。
コンピュータのロック
Win-L
押し方はWindowsキーを押しながら「L」キー
突然会議に召集を掛けられた場合には、すかさず「Win-L」して席を外す。
番外編
普段からコマンドプロンプトを使う事が多い私は、デスクトップにコマンドプロンプトのショートカットを貼り、そのショートカットのプロパティでショートカットーキーを「Ctrl + Shift + Alt + F12」に設定している。
これでどの画面からでも「Ctrl + Shift + Alt + F12」でコマンドプロンプトを起動出来る。
基本的にはオリジナルの設定を変える事はしないほうです。便利だと思ったら付け足すくらい。
ただvimrcは、もう911行もある...。
vimrcでどんな事やってるかについては、また違うエントリで...

2007/02/07

はてな
おそろしやおそろしや...

むかーしむかし、Microsoft Visual J++という道具があったそうな...
その道具では、関数呼出の参照渡しを実現するために、配列を渡してJNI内部で値を設定するといった、奇怪な手法が使われておりましたとさ。

さて話は現代に移り、Microsoft Visual J#という道具が巷では出回っていると聞き、さっそく試した私は、腰を抜かしてしまいそうになりました。
public class Test
{
    public static void test1(int a) { a = 2; }
    public static void test2(/** @ref */ int a) { a = 2; }
    public static void main(String[] args) {
        int b = 3;
        test1(b); System.out.println(b);
        test2(b); System.out.println(b);
    }
}
まさか、こんな結果になりますとは...

Javaという言語仕様まで変えてしまうとは...

おそろしや、おそろしや...


#まぁ、Javaって言ってない(J#)から、いいんですか...
#そうですか...

はてな
ただいま、JavaとCOMを使ったお仕事をしているんですが、どうも正常に動かないものがありまして、困っておりました。

どんな現象かといいますと、Microsoft AgentをAgentObjectsから起動した時に、ConnectedというBOOL型のプロパティをTRUEに設定してやるのですが、どうやらJavaから渡していた値trueが、VARIANT変換により1になっていた事が原因していました。

まぁ、1だしfalseじゃないなら動作するのが一般的なアプリでしょ...と思ってましたが、どっこいMSAgent殿は例外も出さずにConnectedをFALSEに設定して下さいました。

実際、COM上ではBOOLはVARIANT_TRUEもしくはVARIANT_FALSEを設定するのがお決まりで、VARIANT_TRUEは
((VARIANT_BOOL)0xffff)
と宣言されていました。C++上でのtrueとは値が異なる訳です。

まぁ、それは自分のミスとして...

きっとMSAgentのConnectedプロパティ処理では
if (VARIANT_TRUE == arg) {
  // Connected 設定時の処理...
}
というコードが書かれているのだと思うのですが、これは
if (VARIANT_FALSE != arg) {
  // Connected 設定時の処理...
}
って書くべきなんじゃないかな...

ちなみに、Visual Studioのウォッチエリアに追加した、1の値を持つ問題のVARIANT変数は、VT_BOOL:Trueと表示されていました。

2007/01/18

はてな
なんか寝つけないので、もひとつ愚痴...
最近、お仕事でJava使ってます。

といってもJavaの画面上にはActiveX(Ocx)が張りついてます。しかもそのActiveXって.NETで出来てるんです。どんなシステムなのかと...苦笑
まぁそれが言いたいのでなく、COMやATLをJavaアプリで動かすので、Javaのメインスレッドを食われない用に、STAやATLで作ったOcxは別スレッド起こして実行してます。
なんかこういう場合にも、メインスレッドを汚ない(出来ればCOMなんか関与しない)ようなコードが、簡単に書けないものか...

非常にメンドイです。

そうそう今日職場で休憩時間にMSから出てるPowerShellっていう管理者用(?)シェルを試してみました。
感想としては、まさしく...「コマンドプロンプトに.NETという毛を生やした」というのが相応しく(いや、変な意味でなく)、私にとってはPowerとまでは行きませんが、違う物としてみれば使える代物なのかもしれません。

ただ、exeもパス内のものが実行出来るのですが、「startコマンド」が使えない。私にはダメージが大きすぎる。
私は仕事中はだいたい70〜80%をコマンドプロンプトの中で生活しますから、たまにエクスプローラを開くときなんかは、「メニューから...」なんて事はしないんですよね。「cd」してエクスプローラが開きたくなったら
C:\foo\bar\> start .
ってやるんです。
この「startコマンド」がないと、まるで周りからはPCド素人に見えてしまうんですよ。私...

マイクロソフトさん、私を助ける意味でもPowerShellに「startコマンド」を付けて下され...


マイクロソフトで思い出しました...
今日IronPythonを試しました。以前に少し触った事はあったのですが、MSエバンジェリストのブログで、「IronPythonを使ったMSAgentのサンプル」を見つけたので、試してみたんです。
ほう...確かに動く。


...で?
これってpythonのwin32com使ってもおんなじやん...
まぁアセンブリ参照みてモジュールベースのコーディングが出来るのかもしれないんですが、pythonって呼出フック出来るから、結局似たようなコードになるんじゃ...
ちなみにExcelを操作するpythonのコードは...
import win32com.client
xlApp=win32com.client.Dispatch("Excel.Application")
xlApp.Visible=1
xlApp.WorkBooks.Add()
sheet=xlApp.Sheets(1)
sheet.Cells(1, 1).Value="Hello Python"
こんな感じ?じゃぁ、「.NET」である必要って何?

あと余談ですが、MSAgentってSTAでしか動かないんすね。おまけにイベントシンク(IAgentNotifySink/IAgentNotifySinkEx)ってInvoke呼出してくれないし...泣
汎用ディスパッチシンクを呼ばせるには、IDispatchを継承してQueryInterfaceで嘘を返してあげればいいの?
#GetTypeInfoCountもGetTypeInfoも呼ばれない、IAgentNotifySinkを継承してないインスタンスをRegisterメソッドに渡すとエラー出るし...


さぁいい加減に寝ないと、死ぬぞ...

2006/10/05

はてな
ちょっとお仕事でJava&ActiveXを触らなければならなくなりました。
まぁサンプルがてら...って事で、JavaのCanvas上にActiveXを乗っけるサンプルを作ってみました。

適当にプロパティ取得処理と設定処理を作って、後はIDispatchのinvokeを叩ける仕組みを作りました。
さらにイベントプロキシから、Javaクラス内に持つ同名の関数を呼び出し、イベントハンドラもサポートして見ました。
ちょっと引数がオブジェクト配列になってるのが少しイヤン...ではありますが。
とりあえず動いたので、キャプチャ

JavaActiveX

#ちなみに動画の人は私じゃないですから...

新規投稿