hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。
MakeHPI/cpp/chapter2.5 - HSP開発wiki
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS

スクリプトから値を渡しプラグインから結果を返す

  1. 文字列型を受け取ることが出来たので、様々な値を渡し、加工してHSP側に結果を返してみる。
  2. 命令・関数の両方で動作するようにしてみる。
  3. 関数形式をサポートしているので、システム変数は使用しない。


  • 使用コンパイラ : VC++ 6.0
  • SDK : hspsdk31b8

様々な型をプラグインに渡したり、様々な型をプラグインから受け取ったりしたいので、5つの関数に分けました。
また、それぞれを関数・命令の両方に対応させてみます。
(命令にすると意味がなくなるものがありますが、練習のために命令にも対応してみました)
以下が、それぞれの目的と それらの命令と関数の使用例です。

  • 指定した色で背景を塗りつぶす。【目的:整数値(引数)→画面描画】
      1
      2
    
     
     
    
        SetBGColor R, G, B                   // 命令形式の例
        bState =SetBGColor( R, G, B )        // 関数形式の例
    
  • 引数に渡した文字列を小文字にして返す。【目的:文字列(引数)→文字列】
      1
      2
    
     
     
    
        ToLowerCase "HelloWorld!"            // 命令形式の例(無意味です)
        sLC = ToLowerCase( "HelloWorld!" )   // 関数形式の例
    
  • 引数に渡した文字列の文字数を返す。【目的:文字列(引数)→整数値】
      1
      2
    
     
     
    
        CountLetter "HelloWorld!"            // 命令形式の例(無意味です)
        nNum = CountLetter( "HelloWorld!" )  // 関数形式の例
    
  • 引数に渡した度数を弧度に変換して返す。【目的:実数値(引数)→実数値】
      1
      2
    
     
     
    
        DegToRad 180                         // 命令形式の例(無意味です)
        vRad = DegToRad( 180 )               // 関数形式の例
    
  • 引数に渡した変数yの内容を変数xにコピーする。【目的:変数(引数)→変数(引数)】
      1
      2
    
     
     
    
        CopyVariable x, y                    // 命令形式の例
        vType = CopyVariable( x, y )         // 関数形式の例
    

考えたこと

戻り値の型情報を nCmd の値に含めれば、便利な気がします。

+  アイディアA

メモリを節約するために、一つの動的メモリを使いまわす方法もあるようです。

+  アイディアB

今回は、動的メモリが必要なときだけアイディアBを使い、不必要なときは、静的メモリを使うようにしてみます。
各々の関数に戻り値用ポインタを渡すときは、参照渡しをします。

ソースコード

+  メイン
+  ヘッダ
+  _CountLetter?.cpp
+  _ToLowerCase?.cpp
+  _SetBGColor.cpp
+  _DegToRad?.cpp
+  _CopyVariable?.cpp
+  サンプルスクリプト


+  変更点
int _CountLetter( int &count ){
引数 :int型ポインタ
関数値:HSPVAR_FLAG_INT
  1. code_gets()で文字列ポインタを取得し、lstrlen()によって文字数をカウントします。
int _ToLowerCase( void *&pRet ){
引数 :char *型ポインタ
関数値:HSPVAR_FLAG_STR
  1. code_gets()で文字列ポインタを取得し、引数で受け取った動的メモリをhspexpand()で拡張して移します。
  2. あとは、CharLower?()で小文字に変換するだけです。
int _SetBGColor( int &success ){
引数 : int型ポインタ
関数値: HSPVAR_FLAG_INT
  1. (BMSCR *)getbmscr( active_window )により、アクティブウィンドウのBMSCR構造体を取得しています。
  2. bm->hdc でデバイスコンテキストハンドルを、bm->sxやbm->syでウィンドウのサイズを取得します。
  3. bms_send()をつかって、実画面にコピーします。
int _DegToRad( double &rad ){
引数 : double型ポインタ
関数値: HSPVAR_FLAG_DOUBLE
  1. math.hをインクルードし、fmodを有効にしています。取得した実数を±360内に修正します。
  2. 負の場合は360を足して正に直します。(例:-270deg = 90deg)
int _CopyVariable( int &type ){
引数 : int型ポインタ
関数値: HSPVAR_FLAG_INT
  1. code_getva()により、APTR値とPVAL構造体ポインタを取得します。
  2. 変数の型はpvalSrc->flagで取得します。
  3. 配列変数の可能性もあるので、まず配列の指定要素(APTR)をPValのオフセットメンバに指定します。
  4. 次に、ストレージコアファンクションを利用します。(HspVarProc?構造体を取得)
  5. 最後にGetPtr?()関数を呼び出して、指定要素の値(のポインタ)を取得します。
  6. コピーする際は、code_setva()にAPTR,PVAL,型,値の先頭アドレスを渡します。

comment by りさ

コメント

  • ご迷惑おかけしますm(_ _)m 勝手にページ作ったら、ダメだったりしますか? 消しちゃっても構いません(^^; -- りさ 2007-04-11 (水) 03:28:30
  • code_getsで取得したポインタ (strprm)はプラグイン側で解放してはいけないと思います。(そもそも hspmalloc で確保されているかどうかもわかりませし・・・)
    あと_ToLowerCase?内で確保した領域(string)が解放されていませんね。 -- naznyark? 2007-04-12 (木) 02:20:37
  • それとwikiの性質上バイナリファイルの添付は潜在的なリスクが大きいのでやめたほうが良いのではないかと思います。(悪意ある差し替えが可能ですから) -- naznyark? 2007-04-12 (木) 02:27:16
  • 添付してあるDLLのことですね?分かりました、さっそく削除します(^^ -- りさ 2007-04-12 (木) 03:15:36
  • naznyarkさん、アドバイス本当にありがとうございますM(_ _)Mばかなんで調べならがやっている状態なんです(><; -- りさ 2007-04-12 (木) 03:25:55
  • stringはこの関数の戻値として返しているので、関数内では解放できませんよね(?w?“猫でも分かる・・”って本を読みながらやってるんですけど、static か extern キーワードを使えばいいんでしょうか? 猫ちゃんのが頭いいですね [worried2]
  • あと思ったのですが、chapter2 でも text と title の動的メモリが解放出来てない気がするのですが、どうなのでしょう?? -- りさ 2007-04-12 (木) 03:40:25
  • > あと思ったのですが、chapter2 でも ...
    確かに解放していません。chapter2 のページの下のほうにそのあたりについて書いてあります。
    > static か extern キーワードを使えばいいんでしょうか ...
    方法はいろいろありますが、一例として最近の私の好みはこんなやり方です。
    (初期化時に確保した領域を大きさを拡張しながら使いまわします。)
    (ポイント部分だけでコンパイルできませんから雰囲気だけをつかんでください・・・)
    +  一例

    -- naznyark? 2007-04-13 (金) 03:50:00

  • お返事ありがとうございます [kita] chapter2のページ下は読んだのですが、あれでは文字列長に強い制限がかかってしまいますし、結局のところ解決する方法が分からないままでした(^^;

    見せて頂いた例は、とっても難しくて・・・(^^;;
    でもつまり、全ての関数に同一の“戻り値用”のポインタを渡して、それをそれぞれの関数内で設定して、 ポインタが指す型を関数値としてfunction側に戻してるってことですよね。
    動的メモリの確保は、初期化時に1回だけ(同時に複数必要ならば、複数分を確保しなきゃですよね)で、 解放もtermfuncで1回だけ。

    動的なメモリが必要ない部分も、他に合わせて動的メモリ使うとスムーズ、ってことでしょうか。
    (頭の中で整理中(^c^Gスミマセン。あたしのメモってことで。今からやってみますっ [bsmile2] ありがとうございます -- りさ 2007-04-13 (金) 04:48:57

  • 使用するSDKのバージョンを書くだけにして、SDKそのものは添付しないほうがいいと思います。あと変に名前を2.5にしないで連番でつくっていってよかったのに^^; -- kz3 2007-04-13 (金) 05:03:37
  • kz3さん、お世話になっています。SDKも添付しないほうが宜しいのでしょうか? とりあえず今から削除しますっ [ojigi] -- りさ 2007-04-13 (金) 05:05:23
  • 「動的メモリが必要ない」といってる時点で動的メモリは必要ないんじゃ...必要のないものは、書かなければスムーズに開発できますね。 -- kz3 2007-04-13 (金) 07:30:39
  • 分かりました、ありがとうございますm(_ _)m不必要な部分は、静的にしてみます。

    間違えていたようです、“同時に複数必要ならば、複数分を確保しなきゃですよね”各々の関数内で複数の動的メモリが必要な
    場合は、それぞれ関数内でメモリ確保・解放すればいいんですね。-- りさ 2007-04-13 (金) 15:27:04

  • 関数値(戻り値の型)で、静的・動的を使い分けてみました [kita2] 〜〜2 というファイル名でUPしました。上手にできたかもです(^^ -- りさ 2007-04-13 (金) 16:25:27
  • りささん...関数の仮引数が変ですよ。(int &count) -- kz3 2007-04-13 (金) 19:50:48
  • ここの
    http://www.s-cradle.com/developer/sophiaframework/tutorial/Cpp/reference.html

    『参照渡し』というのを参考にしてみたのですが。すみません、どこが変なのか分かりません。教えて頂けないでしょうか? [ojigi] -- りさ 2007-04-13 (金) 20:44:47

  • あ。失礼しました。これはC++の文法なんですね...。C++は全くわかりません [worried2] -- kz3 2007-04-13 (金) 21:49:50
  • いえ、アドバイスありがとうございます [smile2] -- りさ 2007-04-13 (金) 21:58:49
  • >動的メモリ使うとスムーズ
    たぶんnaznyarkさんのスッキリまとまったサンプルを指しているのでしょうか。これはスムーズというよりメモリを節約しているだけです。まぁ自分のスキルに合わせたコーディングをしていけばいいと思います。メモリ管理に興味があったら身近なところに実装例がありますよ(strbuf.cpp)。これが理解できれば動的メモリは怖くありません^^ -- kz3 2007-04-13 (金) 22:21:59
  • >スッキリまとまったサンプルを指しているのでしょうか
    はい、スゴイなぁと。
    strbuf.cpp見てみましたら、非常に難しいですね [au2] でも仰る通り、動的メモリを理解するには、一番のサンプルかもしれません。頑張ってみます [a] HDC を渡すのではなく HDC hdc = ( (BMSCR *)getbmscr( active_window ) )->hdc;
    で、アクティブウィンドウに描画するという方法もあるのですね・・・ -- りさ 2007-04-13 (金) 23:54:00
  • 引数の参照渡しは関数呼び出し部を見ただけでは実引数に指定した変数が変更される可能性を読み取りにくいので注意しましょう。 -- naznyark? 2007-04-14 (土) 01:24:28
  • はい分かりました、ありがとうございます。少し変更してみますm(_ _)m戻り値は、関数・命令のどちらも必要なので、全てを参照渡しにするか、全てをポインタ渡し(?)にするかどっちかにしてみようと思います。それから、もうすこし実用的なサンプルにもしたいと思います(今のところ、処理内容は全く無意味ですし・・^^;) [hiki2] -- りさ 2007-04-14 (土) 02:33:06
  • ・・・色々やってみたのですが、動的メモリの参照渡しが出来ませんでした [ojigi]
    SetBGColor関数は、active_windowのBMSCR構造体を取得して、hdc,sx,sy を参照する形にしてみました。
    HSPのredraw 0 :color R,G,B :boxf と同じ機能になったと思います(^^ -- りさ 2007-04-14 (土) 17:27:05
  • > 動的メモリの参照渡しが出来ませんでした
    BCC ではこれ↓でできましたが・・・。
    +  テストソース

    -- naznyark? 2007-04-15 (日) 01:11:25

  • あっ、引数は _ToLowerCase?(void *& ) なんですかぁ。ありがとうございますM(_ _)M 図を書いてやったりしたのですが、こんがらがる一方でした。 -- りさ 2007-04-15 (日) 01:47:08
  • int & : int型変数の参照を生成、void * & : void* 型変数の参照を生成、という感じです。 -- naznyark? 2007-04-15 (日) 02:12:24
    • 「参照を生成」でなく「参照として宣言」のほうが正しい表現でした。-- naznyark?
  • なるほど、そうやって考えればいいんですね。型の形だけを考えればいいなんてスゴイ分かり易いです。とてもよく理解できました [bsmile2] ありがとうございます! -- りさ 2007-04-15 (日) 02:39:03
  • SDKのサンプルを調べながらやったら、実数も変数も扱えるようになりました(多分^^;)naznyarkさん、kz3さん、どうもありがとうございます [kita2] 残るわ・・システム変数に代入するくらい・・・でしょうか・・。これ以上、関数増やすとゴチャゴチャになってしまうような気がしますし。 -- りさ 2007-04-15 (日) 17:29:23
  • それと、chapter2.5なんて、勝手に作ってよかったのでしょうか?名前変えた方がいいでしょうか?? -- りさ 2007-04-15 (日) 17:40:44
  • CopyVariable? の基本はそれでいいんですが x と y の型が違う場合、また x が配列変数(の先頭の要素でない)場合は問題がありますよ。
    それとその書式では x → y のコピー処理ではなく x ← y のコピー処理のほうが一般的のような・・・。 -- naznyark? 2007-04-16 (月) 01:05:02
  • 仰るとおりx←yが一般的のようでした(^^;;直してみます。x と y の型が違う場合
    code_setva( pvalDest, aptrDest, type, pvalSrc->pt );
    では、型が変えられないのでしょうか? その前に、
    pvalDest->flag = type = pvalSrc->flag;
    として、受け取り側の変数の型を変えておけばいいのですか? -- りさ 2007-04-16 (月) 01:23:44
  • すいません。code_setva は自動で型変換しますね。勘違いでした。-- naznyark? 2007-04-16 (月) 01:47:50
  • いえ、それより配列変数が渡された場合の問題とはなんなのでしょうか?
    x = 3, 5
    CopyVariable? x(1), y
    とすると、x(1)の内容がyにちゃんとコピーされているようなんですけど・・・他に問題が起きる可能性があったりするのでしょうか? -- りさ 2007-04-16 (月) 01:56:57
  • ごめんなさい、kz3さんが、“連番でよかった”って言ってくれてました。すみません。今から連番に直せるのでしょうか? -- りさ 2007-04-17 (火) 00:40:12
  • >配列変数...
    本当に正しく動いていますか?
    Everything is expanded.Everything is shortened.
      1
      2
      3
      4
      5
    
     
     
     
     
     
    
        variable = 10000, 11111
        CopyVariable variable(0), x
        mes x
        CopyVariable variable(1), x
        mes x

    それと DegToRad? では fmod を使ったり引数が負のときも考えた方が良いと思います。 -- naznyark? 2007-04-17 (火) 02:30:56
  • >本当に正しく動いていますか?
    すみません、x←y の場合の配列xばかり考えていましたm(_ _)m反省してます [ojigi]
    ご指摘頂いた通り、fmodを使って剰余を求め、負の場合は単純に360を加算して回避してみることにしました。
    でも未だに配列要素が渡せないままです。
    aptrポインタが配列要素の値を指していること、pval->pt が変数の値へのポインタであること、配列はこのアドレスから連続して確保されていることまで理解できました。色々やっているのですが、なかなか取得出来ない状態です。なんとか頑張ってみます! -- りさ 2007-04-17 (火) 03:55:45
  • 関数形式をサポートしているので、システム変数に関数値と同じ結果を代入するのは無意味だと思ったので、システム変数の部分を消しました。
    pRef_retvalはstr型にしか使わないのでpRef_svalに変更してみました。出来たところまで、アップロードしておきます(^^
    -- りさ 2007-04-17 (火) 04:05:53
  • 配列要素の実体ポインタはストレージコアファンクションを使用して取得するのが基本です。(仕様が公開されている型なら自前で算出することもできますが・・・)
    PVal 構造体の offset メンバに対象要素の APTR 値を設定し、getproc 関数でその変数の型の HspVarProc? 構造体を取得して GetPtr? 関数を呼び出します。 -- naznyark? 2007-04-18 (水) 01:42:35
  • ありがとございます、もう少しゴニョゴニョやってみます! -- りさ 2007-04-19 (木) 03:27:12
  • getproc 関数というのは、hsp3plugin.h で getproc exinfo->HspFunc_getproc と定義されているのですね
  • type = pvalSrc->flag;
    pvalSrc->offset = 0;
    HspVarProc? *hvp = getproc( type );
  • ここまでは出来たのですが、GetPtr?関数を呼び出せません。ちゃんと定義されているはずなんですが・・(汗 -- りさ 2007-04-19 (木) 23:21:11
  • hvp->GetPtr?(pvalSrc)で出来ませんか?関数ポインタへの間接参照(呼び出し)ですよー。一通りできたらページをまとめる必要がありますね^^; -- kz3 2007-04-20 (金) 00:22:00
  • b9正式リリースはまだかなぁ [hu] -- kz3 2007-04-20 (金) 00:26:44
  • >hvp->GetPtr?(pvalSrc) 出来ました!! そして急いで関数ポインタの勉強を始めました [ojigi]
    ホントにありがとうございます。今から載せますっ
  • code_setva( pvalDest, aptrDest, type, hvp->GetPtr?(pvalSrc) ); とも書けますが、(あたしが)分かり易いように、一度 PDAT *型変数に代入しています。
  • >をまとめる必要がありますね >ごちゃごちゃですよね(^^;;
    >b9正式リリース >待ち遠しいですね。でも本音はHSP3.1が出て欲しいです^^/
  • naznyarkさんとkz3さんのおかげで、HSPのことやプラグインのこと、そしてC言語のことなど、とても勉強になりましたM(_ _)M そしてHSP開発者のおにたまさんのスゴさを再実感しました(泣笑)
    ところで実わ、HSPエディタを作って見ようと思って色々調べてみたのですが、今の実力では到底不可能なことを知りました(涙 コントロールだとかコンポーネントだとか・・・ [worried2]世界は広いですね [smile3]
    Everything is expanded.Everything is shortened.
      1
      2
      3
    
     
     
     
    
        // 整数型の変数の内容を取得
        if ( pval->flag == HSPVAR_FLAG_INT )
            int val = *(int *)(pval->pt);
  • 変数の値を取得する方法を載せなかったのですが、こんなカンジで大丈夫ですよね?
  • 違いました(汗 よく考えたら、_CopyVariable?関数と同じようにすれば取得できますね [tere]
  • どうやってまとめればいいのでしょう? とりあえず、『目標』の説明を増やしました。 -- りさ 2007-04-22 (日) 03:44:05
  • 余計かもしれませんが、main.cpp にも説明を加えました。 -- りさ 2007-04-22 (日) 16:15:20
  • そういえば hsp3plugin.cpp にHSPウィンドウのバッファ→実画面の画像コピー用関数( bms_send )が用意されていますよ。(私は使ったことないので忘れてました。) -- naznyark? 2007-04-25 (水) 01:06:13
  • そういえば、前に教わった気がしますっ!
    bms_send(bm,0,0,bm->sx,bm->sy); で、画面を更新するものですよね。しかも試してみたら、redraw スイッチがオフのときは描画されないみたいです [kita2] ってことは、描画系の命令(関数)には全部このようにした方がいいってことでしょうか??
    処理の時間もスイッチの判定だけのような気がするので、小さいものだと思うのです。 -- りさ 2007-04-26 (木) 18:45:50
  • > 描画系の命令(関数)には全部このようにした方がいいってことでしょうか??
    描画系命令・関数の処理の冒頭に判定をいれるのではなく BMSCR の hdc メンバのデバイスコンテキストに描画したあとに bms_send を呼び出すようにします。
    こうすることで標準の描画系命令と同様の
    redraw モードが 0 のときはバッファ画面への描画のみで実画面を更新しない。
    redraw モードが 1 のときはバッファ画面へ描画して実画面も更新する。
    という動作にすることができます。 -- naznyark? 2007-04-27 (金) 03:05:11
  • CountLetter?はメモリを確保するのにパラメータの文字列の長さを調べてるから、数えて確保してコピーして数えてって意味がないですね(笑)文字列パラメータをコピーする必要があるのは取得した文字列をほかで利用する場合なので文字列長を数えるくらいならコピーしなくても平気です。 -- kz3 2007-04-27 (金) 20:25:34
  • >という動作にすることができます。>> なるほど、つまりHSPの描画系の命令もこのようにして出来ているわけですねっ。さっそく変更してみました!動作もばっちりです [kita]
    >文字列長を数えるくらいなら>>いえ、ほんとにそうですね(笑)なんかバカでした [tere] 数えて数えてしてました。直したらスゴクすっきりしました!
    naznyarkさん、kz3さんどうもありがとうございますm(_ _)m-- りさ 2007-04-28 (土) 16:46:19
  • そういえばb9でましたネ [kita2] -- りさ 2007-04-28 (土) 17:04:36

URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

添付ファイル:
filesample.hsp
158件 [詳細]
file_SetBGColor.cpp
156件 [詳細]
file_CountLetter.cpp
179件 [詳細]
filemain.cpp
161件 [詳細]
file_CopyVariable.cpp
175件 [詳細]
filehpi.h
176件 [詳細]
file_ToLowerCase.cpp
166件 [詳細]
file_DegToRad.cpp
171件 [詳細]
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS
Last-modified: 2007-04-28 (土) 17:04:36 (2354d)