ホーム 主筆 その他ソフト その他情報 Syuhitu.org English

Windows関連

スクリーンセーバー作成法

半透明ウインドウの性能

bootfont.bin

キャビネット形式

ウインドウスタイルをいじる

Java製ソフトをServiceに登録する

イベントログにメッセージを出力する

コントロールパネルにアイコンを追加する

スクリプトによる拡張1

スクリプトによる拡張2

ガジェットの作成

大容量メモリ

メモリ搭載量の下限に挑む

スパースファイルにする

表示されるアイコンの種類を調べてみた

メモリマップIOとエラー処理

ファイルを作る順番と速度の関係

Cryptography API: Next Generationを使う

Windows 10のアクセントカラー

iSCSIディスクにバックアップを取る

サーバプロセスを分離して実装する

サーバプロセスを分離して実装する - F#

レジストリに大量に書き込む

Solaris関連

OpenGL

Solaris設定

ディレクトリの読み込み

主筆プラグイン開発

マルチスレッドでの開発

door

音を出す

Blade100の正しい虐め方

パッケージの作成

画像入出力

BMPファイル

ICOファイル

ANIファイル

JPEGファイル

減色アルゴリズム

減色アルゴリズムの並列化

その他アルゴリズムなど

自由軸回転

Base64

文字列操作

CPU利用率の取得

正規表現ライブラリ

メタボールを作る

メタボールを作る2

正規表現とNFA・DFA

C言語の構文解析

液晶ディスプレイを解体してみた

iSCSIの理論と実装

単一フォルダにファイルを沢山作る

USB-HUBのカスケード接続

SafeIntの性能

VHDファイルのフォーマット

USBメモリに書き込み続けてみた

主筆プラグインの開発について

[1] 主筆嬢 05/11/01 20:09

最近気がついたんだけど、この「主筆」のプラグインって、すごく作りにくい。

なんとかしろ。

[2] nabiki_t 05/11/01 20:35

んなことはない。気のせいだ。

[3] 主筆嬢 05/11/01 21:15

絶対気のせいなんかじゃない。

だって、引数に与えられた関数ポインタにパラメタ渡して、関数ポインタ取得してその関数ポインタを呼び出すだなんて、絶対におかしい。人のことを馬鹿にしてるのか。

ユーザビリティ最悪。

[4] nabiki_t 05/11/01 22:06

自分の頭が悪いのを棚に上げて文句を言うな。

[5] 主筆嬢 05/11/01 22:45

うるさい。

インターフェースの作りが悪いんだ。

[6] nabiki_t 05/11/01 23:32

しかしまぁ、まじめな話、インタフェースがあまりよろしくないのは、認めざるを得まい。

と言うことで、こんなんラッパクラスを作ってみた。

spf.h 10.3KB

ついでに、これも

PluginFuncID.h 3.2KB

[7] 匿名希望 05/11/02 02:28

馬鹿二人が罵りあっているようにしか見えない……

[8] 主筆嬢 05/11/02 06:33

仕様書とか無いの?

[9] nabiki_t 05/11/02 19:17

無い。これぐらい自分でソース読め。

でも一応使い方を示しておく。

#include "spf.h"

using namespace std;

extern "C" void foo( PFT_GetAPIFunction GetAPIFunction )
{
  CSyuhituPlugin csp( GetAPIFunction );
  try {
    csp.ShowInformationMsgBox( L"メッセージ" );
  }
  catch( CSP_Err r ) {
    printf( "ERROR %d\n", r.LastFunction );
  }
}

まぁ、まずはspf.hというヘッダファイルをインクルードする必要がある。

#include "spf.h"

で、一部stringやwstringを使ってる部分があるから、必要に応じて、デフォルトでstdの名前空間を使用することを宣言しておく。まぁ、上記の例では必要ないがな。

using namespace std;

次に、呼ばれた関数内(ここではfoo)で、CSyuhituPluginクラスのインスタンスを生成する。そのときに、引数として渡された関数ポインタを、コンストラクタに指定する。

CSyuhituPlugin csp( GetAPIFunction );

後は必要に応じてCSyuhituPluginクラスのメンバを呼び出してやればいい。各メンバ関数はAPI関数と1対1で対応しているから、まぁ、悩むことはないだろう。

csp.ShowInformationMsgBox( L"メッセージ" );

あぁ、あと、なんか問題が発生したときには、CSP_Errというオブジェクトが例外として投げられるから、ちゃんとtryブロックが囲んでお入れやった方がいい。そうしないと、例外が発生したときに「主筆」のプロセスが落ちることになる。

[10] 主筆嬢 05/11/02 20:38

ふーん。

まぁ、「一旦関数ポインタを取得する」という手間は省けるかな。

[11] 主筆嬢 05/11/02 20:45

そういえば、>>9のソースの「extern "C"」てなにさ。

[12] nabiki_t 05/11/02 21:23

そりゃ、あれだ。

当然だが、このコードは必ずC++でコンパイルしなきゃならない。でも、そうすると関数名がマングリングされて、「主筆」側から呼び出すことが出来なくなってしまう。

だから、「extern "C"」と記述して、Cのリンケージ規約に従うように宣言するひつようがある。

これは余談だが、もしかしたらプラグイン設定ファイルの呼び出し先関数名に、マングリングを考慮した名前を記述してやれば、呼び出すことが出来るかも知れない。もっとも、そんなことをしなければならない必要性もメリットも無いけどな。

[13] 広告 05/11/02 21:42

[14] 主筆嬢 05/11/02 23:42

こんなプログラムを作って、

#include "PluginFuncID.h"

void foo( PFT_GetAPIFunction GetAPIFunction )
{
  PFT_ShowInformationMsgBox pF =
    (PFT_ShowInformationMsgBox)GetAPIFunction( PFID_SHOWINFORMATIONMSGBOX );
  pF( L"あいうえお" );
}

こんなコマンドでコンパイルしてみたんだけど、

cc -G -o test1.so test1.c

なんか、こんなメッセージが表示されて実行出来ないんだけど。

何とかしろ。

[15] nabiki_t 05/11/02 23:58

>>14

態度でかいな、おまえ。

[16] 名無しさん 05/11/03 00:01

>>15

糞なモンを作る香具師が悪い。

[17] nabiki_t 05/11/03 08:14

>>14

そりゃ、コンパイルの仕方が悪いんだ。

「主筆」の本体は64bitでコンパイルしてある。だが、おまいのコンパイルの仕方だと「test1.so」は32bitのバイナリになる。

Solarisの仕様上、64bitと32bitのオブジェクトモジュールをリンクすることは出来ないから、64bitの「主筆」から32bitの「test1.so」を呼び出そうとすると、失敗する。

だから、SunCCを使ってるんなら、こういう風にコンパイルする必要がある。

cc -xarch=v9 -G -o test1.so test1.c

[18] ぬるぽ 05/11/03 08:37

ぬるぽ

[19] ぬるぽ 05/11/03 09:02

>>18 ガッ

[20] 主筆嬢 05/11/03 11:37

今度はこんなプログラムを作ったんだけど、

#include "PluginFuncID.h"

void foo( PFT_GetAPIFunction GetAPIFunction )
{
  PFT_ShowInformationMsgBox pF =
    (PFT_ShowInformationMsgBox)GetAPIFunction( PFID_SHOWINFORMATIONMSGBOX );
  wchar_t *p = (wchar_t*)malloc( sizeof( wchar_t ) * 100 );
  wscpy( p, L"あいうえお" );
  pF( p );
  free( p );
}

このプラグインを呼び出すと、wscpyのところでプロセスが落ちるんですが。

なんか、mallocでトンチンカンなアドレスが返されるように見えるんですが。

[21] 匿名希望 05/11/03 11:57

そりゃ、おまえの脳みそがトンチンカンだからだろう。

[22] nabiki_t 05/11/03 12:16

>>20

詳しいことは知らないが、どうやらいくつかのヘッダファイルをインクルードしていないのが原因のようだ。

特にmallocは、ヘッダファイル内でdefineされたもので、本当は違う名前らしい。だから、ちゃんとヘッダファイルをインクルードしないと、mallocと言う名前のなんだかよく判らない関数を呼び出すのか、どっか不正なアドレスを呼び出すのかは知らないが、なんかよく判らないアドレスが帰ってくることになる。

だから、上記のプログラムなら、PluginFuncID.h以外に少なくとも<stdlib.h>と<wchar.h>ぐらいはインクルードしなくてはならないはずだ。

[23] 主筆嬢 05/11/03 14:12

主筆の第12版で、PFID_SETCHARの関数を呼んでも、常に偽が帰ってきて、何もおきないんですが。

[24] nabiki_t 05/11/03 14:25

実は、第12版ではSetCharは実装していない。

何もせずPFT_FALSEを返すようになっている。

[25] 主筆嬢 05/11/03 14:31

バグじゃん。

[26] nabiki_t 05/11/03 14:35

バグではありません。仕様です。

なお、第13版でこの仕様は変更される予定です。

[27] 名無しさん 05/11/03 14:48

>>26

DQN Sヨは4ネ

[28] 主筆嬢 05/11/03 15:21

プラグインから、テキストの追加や削除をしたいんだけど、APIにInsertとかDeleteとか無いの?

[29] 広告 05/11/03 15:55

[29] nabiki_t 05/11/03 16:20

>>28

テキストの追加や削除にはReplaceを使う。

追加するときは、

PFT_Replace Replace = (PFT_Replace)GetAPIFunction( PFID_REPLACE );
unsigned long LP = 挿入位置の行;
unsigned long CP = 挿入位置のカラム;
Replace( LP, CP, LP, CP, L"挿入する文字列" );

と、する。

つまり、置換対象の範囲の長さが0ならば、単純な挿入になる、ということ。

削除するなら、

PFT_Replace Replace = (PFT_Replace)GetAPIFunction( PFID_REPLACE );
unsigned long SLP = 削除開始位置の行;
unsigned long SCP = 削除開始位置のカラム;
unsigned long ELP = 削除終了位置の行;
unsigned long ECP = 削除終了位置のカラム;
Replace( SLP, SCP, ELP, ECP, L"" );

と、する。

つまり、置換後の文字列として、長さ0の文字列を指定すれば、単純な削除になる、ということ。

[30] 主筆嬢 05/11/17 20:42

第13版でようやくSetCharが実装されたっていうから、こういうプログラムを作ってみた。

void goo( PFT_GetAPIFunction GetAPIFunction )
{
	PFT_GetLineCount GetLineCount =
		(PFT_GetLineCount)GetAPIFunction( PFID_GETLINECOUNT );
	PFT_GetCharCount GetCharCount =
		(PFT_GetCharCount)GetAPIFunction( PFID_GETCHARCOUNT );
	PFT_SetChar SetChar =
		(PFT_SetChar)GetAPIFunction( PFID_SETCHAR );

	unsigned long LP, CP;
	unsigned long LineCnt;
	unsigned long LineLen;

	if ( !GetLineCount( &LineCnt ) )
		printf( "ERROR GetLineCount\n" );

	for ( LP = 0; LP < LineCnt; LP++ ) {
		if ( !GetCharCount( LP, &LineLen ) )
			printf( "ERROR GetCharCount LP = %d\n", LP );

		for ( CP = 0; CP < LineLen; CP++ ) {
			if ( !SetChar( LP, CP, L'-' ) )
				printf( "ERROR SetChar LP = %d CP = %d\n", LP, CP );
		}
	}
}

で、こういうデータでこのプラグインを動かしてみた。

そしたら、こういう結果になって、

コンソールにはこういう風に表示された。

私としては、全部の文字が'-'になることを期待していたんだけど。

バグってんじゃないの?

[31] nabiki_t 05/11/03 20:45

あぁ、確かにバグってるな。

[34] 主筆嬢 05/11/17 20:47

やっぱバグかよ。

てめぇ、ざけるなよ。

[32] nabiki_t 05/11/03 20:48

おまえのプログラムがバグってるんだ。馬鹿。

行末には改行コードがあるんだ。だから、行末の文字にSetCharしたら改行コードが削除されて、その次の行と連結されるんだ。

つまり、絵で描くとこういう事だ。

下記の状態が、まだSetcharする前の状態だ。

この状態から、赤い所に対してSetCharして'-'を置いたとする。

するとこうなる。

ここでだ。おまえのプログラムでは、行末の\nを-に置き換えた後、次の行を処理するべく、LPに1を足してCPを0にしているだろう? ところが、おまえが考えていた「次の行」は、前の行に連結されちゃって、実際には「その次の行」が来ているわけだ。

その上、行数も減っている。だから、最初予測していた行数回だけLP++をすると、存在しない行に対してGetCharCountをする羽目になる。

と言うことで、おまえのプログラムの実行結果はあれで正しいわけだ。

[33] 主筆嬢 05/11/17 20:50

なんか厭な仕様だな。

[34] nabiki_t 05/11/03 20:52

文句言うな。

ついでに言うと、一番最後の行には、改行コードは存在しないから、そのつもりでな。

[35] 主筆嬢 05/11/17 20:55

ふーん。


連絡先 - サイトマップ - 更新履歴
Copyright (C)  2000 - 2016 nabiki_t All Rights Reserved.