スクリプトから値を渡しプラグインから結果を返す †
- 文字列型を受け取ることが出来たので、様々な値を渡し、加工してHSP側に結果を返してみる。
- 命令・関数の両方で動作するようにしてみる。
- 関数形式をサポートしているので、システム変数は使用しない。
- 使用コンパイラ : 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
|
0x2___ は、文字列型の戻り値を
0x4___ は、整数型の戻り値を
持ちます。
(vartype命令で取得する値と同じ)
これを、関数では、
function( cmd );
switch( cmd & 0xF000 ) {
case 0x2000:
ptr = ref_sval;
*type_res = HSPVAR_FLAG_STR;
break;
case 0x4000:
default:
ptr = &ref_ival;
*type_res = HSPVAR_FLAG_INT;
break;
}
とし、命令では、
code_next();
function( cmd );
とすれば、便利なのではないかと思いました。 -- りさ
|
|
メモリを節約するために、一つの動的メモリを使いまわす方法もあるようです。
+
| | アイディアB
|
- 初期化時に、動的メモリを一つ確保
- そのポインタをそれぞれの関数に渡す
- その関数内で、渡されたアドレスに結果を代入する。関数値は、結果の型(HSPVAR_FLAG_XXX)。
- 終了時に(termfunc内で)、メモリを解放
こうすることによりメモリを節約でき、さらに各々の管理も簡単になると思われます。
|
|
今回は、動的メモリが必要なときだけアイディアBを使い、不必要なときは、静的メモリを使うようにしてみます。
各々の関数に戻り値用ポインタを渡すときは、参照渡しをします。
+
| | メイン
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
|
!
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
!
|
|
!
-
|
|
|
!
-
|
|
!
-
|
!
-
|
|
|
|
|
|
|
|
|
!
| #define WIN32_LEAN_AND_MEAN #include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "hsp3plugin.h"
#include "hspvar_core.h"
#include "hpi.h"
static int Ref_ival; static double Ref_dval; static void *pRef_sval;
static int function( int nCmd )
{
switch( nCmd ) {
case 0x01:
return _ToLowerCase( pRef_sval );
case 0x02:
return _SetBGColor( Ref_ival );
case 0x03:
return _CountLetter( Ref_ival );
case 0x04:
return _DegToRad( Ref_dval );
case 0x05:
return _CopyVariable( Ref_ival );
default:
puterror( HSPERR_UNSUPPORTED_FUNCTION );
}
return 0;
}
static void *reffunc( int *type_res, int cmd )
{
if ( *type != TYPE_MARK ) puterror( HSPERR_INVALID_FUNCPARAM );
if ( *val != '(' ) puterror( HSPERR_INVALID_FUNCPARAM );
code_next();
*type_res = function( cmd );
if ( *type != TYPE_MARK ) puterror( HSPERR_INVALID_FUNCPARAM );
if ( *val != ')' ) puterror( HSPERR_INVALID_FUNCPARAM );
code_next();
switch( *type_res ) {
case HSPVAR_FLAG_INT:
return ( &Ref_ival );
case HSPVAR_FLAG_DOUBLE:
return ( &Ref_dval );
case HSPVAR_FLAG_STR:
return ( pRef_sval );
}
return 0;
}
static int cmdfunc( int cmd )
{
code_next();
function( cmd );
return RUNMODE_RUN;
}
static int termfunc( int option )
{
hspfree( pRef_sval ); return 0;
}
BOOL WINAPI DllEntryPoint(HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved)
{
return TRUE;
}
EXPORT void WINAPI SMP_Register( HSP3TYPEINFO *info )
{
hsp3sdk_init( info ); pRef_sval = hspmalloc( 64 ); info->cmdfunc = cmdfunc; info->reffunc = reffunc; info->termfunc = termfunc; }
|
|
+
| | ヘッダ
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
| #ifndef _SMP_Function_H_
#define _SMP_Function_H_
int _ToLowerCase( void * & );
int _SetBGColor( int & );
int _CountLetter( int & );
int _DegToRad( double & );
int _CopyVariable( int & );
#endif
|
|
+
| | _CountLetter?.cpp
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
-
|
|
|
|
|
|
|
|
|
|
!
| #include <windows.h>
#include "hsp3plugin.h"
int _CountLetter( int &count )
{
char *strprm;
strprm = code_gets();
count = lstrlen( strprm );
return HSPVAR_FLAG_INT;
}
|
|
+
| | _ToLowerCase?.cpp
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
-
|
|
|
|
|
|
|
|
|
|
|
|
!
| #include <windows.h>
#include "hsp3plugin.h"
int _ToLowerCase( void *&pRet )
{
char *strprm;
strprm = code_gets();
pRet = hspexpand( (char*)pRet, lstrlen( strprm ) + 1 );
lstrcpy( (char*)pRet, strprm );
CharLower( (char*)pRet );
return HSPVAR_FLAG_STR;
}
|
|
+
| | _SetBGColor.cpp
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
| #include <windows.h>
#include "hsp3plugin.h"
int _SetBGColor( int &success )
{
int r, g, b, rv;
HDC hdc;
HBRUSH hBrush;
BMSCR *bm;
success = FALSE; bm = (BMSCR *)getbmscr( active_window ); hdc = bm->hdc;
r = (int)code_getdi( 0 );
g = (int)code_getdi( 0 );
b = (int)code_getdi( 0 );
hBrush = CreateSolidBrush( RGB( r, g, b ) );
if ( hBrush == NULL )
return HSPVAR_FLAG_INT;
rv = (int)SelectObject( hdc, hBrush );
if ( ( rv == NULL )||( rv == GDI_ERROR ) )
return HSPVAR_FLAG_INT;
if ( Rectangle( hdc, -1, -1, (bm->sx)+1, (bm->sy)+1 ) == 0 )
return HSPVAR_FLAG_INT;
if ( DeleteObject( hBrush ) == 0 )
return HSPVAR_FLAG_INT;
bms_send( bm, 0, 0, bm->sx, bm->sy);
success = TRUE;
return HSPVAR_FLAG_INT;
}
|
|
+
| | _DegToRad?.cpp
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
| #include <windows.h>
#include <math.h>
#include "hsp3plugin.h"
int _DegToRad( double &rad )
{
double deg = code_getdd(0);
if ( deg )
deg = fmod( deg, 360 );
if ( deg < 0 )
deg += 360;
rad = (3.1415926536 * deg)/180;
return HSPVAR_FLAG_DOUBLE;
}
|
|
+
| | _CopyVariable?.cpp
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
| #include <windows.h>
#include "hspvar_core.h"
#include "hsp3plugin.h"
int _CopyVariable( int &type )
{
APTR aptrSrc, aptrDest;
PVal *pvalSrc, *pvalDest;
aptrDest = code_getva( &pvalDest );
aptrSrc = code_getva( &pvalSrc );
type = pvalSrc->flag;
pvalSrc->offset = aptrSrc;
HspVarProc *hvp = getproc( type );
PDAT *pdat = hvp->GetPtr(pvalSrc);
code_setva( pvalDest, aptrDest, type, pdat );
return HSPVAR_FLAG_INT;
}
|
|
+
| | サンプルスクリプト
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
| #regcmd "_SMP_Register@4","smp.dll"
#cmd ToLowerCase 0x01 #cmd SetBGColor 0x02 #cmd CountLetter 0x03 #cmd DegToRad 0x04 #cmd CopyVariable 0x05
screen 0, 640, 480
pos 20, 20
color 0, 0, 255
SetBGColor 255, 128
text = "AbCですニャ"
mes "青い文字を書きます(^^"
mes
mes ToLowerCase( text )
mes
mes "文字数 " + CountLetter( text ) + " = " + strlen( text )
text = "\n\nすごくながいメッセージを表示します。\n何文字までいけるのかな?\n"
text += "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz_3.1B8_エイチエスピー\n"
text += "HSP.hsp.HSP.hsp.HSP.hsp.HSP.hsp.HSP.hsp.HSP.hsp.HSP.hsp.HSP.hsp.HSP.hsp.X"
text = ToLowerCase( text )
mes text
r = 0
mes "度数法の" + strf( "%4d", r ) + "は、弧度法で" + DegToRad( r ) + "です。"
r = -90
mes "度数法の" + strf( "%4d", r ) + "は、弧度法で" + DegToRad( r ) + "です。"
r = 180
mes "度数法の" + strf( "%4d", r ) + "は、弧度法で" + DegToRad( r ) + "です。"
r = 540
mes "度数法の" + strf( "%4d", r ) + "は、弧度法で" + DegToRad( r ) + "です。\n"
old = 111
mes "["+old+"] のvartypeは"+CopyVariable(new,old)+"(="+vartype(old)+")です。"
mes "["+new+"] コピーしました。"
old = 222, 333
mes "["+old(0)+"] のvartypeは"+CopyVariable(new,old(0))+"(="+vartype(old(0))+")です。"
mes "["+new+"] コピーしました。"
mes "["+old(1)+"] のvartypeは"+CopyVariable(new,old(1))+"(="+vartype(old(1))+")です。"
mes "["+new+"] コピーしました。"
|
|
+
| | 変更点
|
- 2007-04-12
hspfree()でcode_getsより取得したポインタを解放しようとしていた間違いを修正しました。
- 2007-04-13
1つの動的メモリを使いまわすようにしました。
動的メモリが必要ない関数は、出来る限り動的メモリを使わないようにしました。
- 2007-04-14
_SetBGColor関数は、成功・失敗を関数値としました。
また、hdc やウィンドウサイズをBMSCR構造体から取得するようにしました。
- 2007-04-15
_ToLowerCase関数でも、参照渡しが出来るようになりました。
実数型のサンプルとして、_DegToRad関数を作成しました。
変数のサンプルとして、_CopyVariable関数を作成しました。
- 2007-04-20
_CopyVariable関数で配列の指定要素をコピー出来るようになりました。
- 2007-04-28
_CountLetter関数で、不必要なコピーをしていたのを修正しました。
_SetBGColor関数で、bms_sendにより実画面コピーをするように修正しました。
|
|
int _CountLetter( int &count ){
引数 :int型ポインタ
関数値:HSPVAR_FLAG_INT
- code_gets()で文字列ポインタを取得し、lstrlen()によって文字数をカウントします。
int _ToLowerCase( void *&pRet ){
引数 :char *型ポインタ
関数値:HSPVAR_FLAG_STR
- code_gets()で文字列ポインタを取得し、引数で受け取った動的メモリをhspexpand()で拡張して移します。
- あとは、CharLower?()で小文字に変換するだけです。
int _SetBGColor( int &success ){
引数 : int型ポインタ
関数値: HSPVAR_FLAG_INT
- (BMSCR *)getbmscr( active_window )により、アクティブウィンドウのBMSCR構造体を取得しています。
- bm->hdc でデバイスコンテキストハンドルを、bm->sxやbm->syでウィンドウのサイズを取得します。
- bms_send()をつかって、実画面にコピーします。
int _DegToRad( double &rad ){
引数 : double型ポインタ
関数値: HSPVAR_FLAG_DOUBLE
- math.hをインクルードし、fmodを有効にしています。取得した実数を±360内に修正します。
- 負の場合は360を足して正に直します。(例:-270deg = 90deg)
int _CopyVariable( int &type ){
引数 : int型ポインタ
関数値: HSPVAR_FLAG_INT
- code_getva()により、APTR値とPVAL構造体ポインタを取得します。
- 変数の型はpvalSrc->flagで取得します。
- 配列変数の可能性もあるので、まず配列の指定要素(APTR)をPValのオフセットメンバに指定します。
- 次に、ストレージコアファンクションを利用します。(HspVarProc?構造体を取得)
- 最後にGetPtr?()関数を呼び出して、指定要素の値(のポインタ)を取得します。
- コピーする際は、code_setva()にAPTR,PVAL,型,値の先頭アドレスを渡します。
comment by りさ
- ご迷惑おかけしますm(_ _)m 勝手にページ作ったら、ダメだったりしますか? 消しちゃっても構いません(^^; -- りさ
- code_getsで取得したポインタ (strprm)はプラグイン側で解放してはいけないと思います。(そもそも hspmalloc で確保されているかどうかもわかりませし・・・)
あと_ToLowerCase?内で確保した領域(string)が解放されていませんね。 -- naznyark?
- それとwikiの性質上バイナリファイルの添付は潜在的なリスクが大きいのでやめたほうが良いのではないかと思います。(悪意ある差し替えが可能ですから) -- naznyark?
- 添付してあるDLLのことですね?分かりました、さっそく削除します(^^ -- りさ
- naznyarkさん、アドバイス本当にありがとうございますM(_ _)Mばかなんで調べならがやっている状態なんです(><; -- りさ
- stringはこの関数の戻値として返しているので、関数内では解放できませんよね(?w?“猫でも分かる・・”って本を読みながらやってるんですけど、static か extern キーワードを使えばいいんでしょうか? 猫ちゃんのが頭いいですね
- あと思ったのですが、chapter2 でも text と title の動的メモリが解放出来てない気がするのですが、どうなのでしょう?? -- りさ
- > あと思ったのですが、chapter2 でも ...
確かに解放していません。chapter2 のページの下のほうにそのあたりについて書いてあります。
> static か extern キーワードを使えばいいんでしょうか ...
方法はいろいろありますが、一例として最近の私の好みはこんなやり方です。
(初期化時に確保した領域を大きさを拡張しながら使いまわします。)
(ポイント部分だけでコンパイルできませんから雰囲気だけをつかんでください・・・)
+
| | 一例
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
-
|
|
|
|
|
|
|
|
!
-
|
|
|
|
!
-
|
|
|
!
-
|
|
|
!
-
|
|
|
|
|
|
|
|
|
!
-
|
|
|
|
|
|
|
|
|
|
|
|
|
!
| static void *pRef_retval;
static void function( int nCmd )
{
case 0x2001:
return _ToLowerCase( &pRef_retval );
case 0x4001:
return _SetBGColor( &pRef_retval );
case 0x4002:
return _CountLetter( &pRef_retval );
}
static void *reffunc( int *type_res, int cmd )
{
*type_res = function( cmd );
return ( pRef_retval );
}
static int termfunc( int option )
{
hspfree( pRef_retval );
}
EXPORT void WINAPI SMP_Register( HSP3TYPEINFO *info )
{
pRef_retval = hspmalloc( 64 );
}
int _CountLetter( void **ppRet )
{
strprm = code_gets();
*ppRet = hspexpand( *((char**)ppRet), sizeof( int ) );
**((int**)ppRet) = lstrlen( strprm );
return HSPVAR_FLAG_INT;
}
int _ToLowerCase( void **ppRet )
{
strprm = code_gets();
*ppRet = hspexpand( *((char**)ppRet), lstrlen( strprm ) + 1 );
lstrcpy( *((char**)ppRet), strprm );
CharLower( *((char**)ppRet) );
return HSPVAR_FLAG_STR;
}
|
|
-- naznyark?
- お返事ありがとうございます chapter2のページ下は読んだのですが、あれでは文字列長に強い制限がかかってしまいますし、結局のところ解決する方法が分からないままでした(^^;
見せて頂いた例は、とっても難しくて・・・(^^;;
でもつまり、全ての関数に同一の“戻り値用”のポインタを渡して、それをそれぞれの関数内で設定して、
ポインタが指す型を関数値としてfunction側に戻してるってことですよね。
動的メモリの確保は、初期化時に1回だけ(同時に複数必要ならば、複数分を確保しなきゃですよね)で、
解放もtermfuncで1回だけ。
動的なメモリが必要ない部分も、他に合わせて動的メモリ使うとスムーズ、ってことでしょうか。
(頭の中で整理中(^c^Gスミマセン。あたしのメモってことで。今からやってみますっ ありがとうございます -- りさ
- 使用するSDKのバージョンを書くだけにして、SDKそのものは添付しないほうがいいと思います。あと変に名前を2.5にしないで連番でつくっていってよかったのに^^; -- kz3
- kz3さん、お世話になっています。SDKも添付しないほうが宜しいのでしょうか? とりあえず今から削除しますっ -- りさ
- 「動的メモリが必要ない」といってる時点で動的メモリは必要ないんじゃ...必要のないものは、書かなければスムーズに開発できますね。 -- kz3
- 分かりました、ありがとうございますm(_ _)m不必要な部分は、静的にしてみます。
間違えていたようです、“同時に複数必要ならば、複数分を確保しなきゃですよね”各々の関数内で複数の動的メモリが必要な
場合は、それぞれ関数内でメモリ確保・解放すればいいんですね。-- りさ
- 関数値(戻り値の型)で、静的・動的を使い分けてみました 〜〜2 というファイル名でUPしました。上手にできたかもです(^^ -- りさ
- りささん...関数の仮引数が変ですよ。(int &count) -- kz3
- ここの
http://www.s-cradle.com/developer/sophiaframework/tutorial/Cpp/reference.html
『参照渡し』というのを参考にしてみたのですが。すみません、どこが変なのか分かりません。教えて頂けないでしょうか? -- りさ
- あ。失礼しました。これはC++の文法なんですね...。C++は全くわかりません -- kz3
- いえ、アドバイスありがとうございます -- りさ
- >動的メモリ使うとスムーズ
たぶんnaznyarkさんのスッキリまとまったサンプルを指しているのでしょうか。これはスムーズというよりメモリを節約しているだけです。まぁ自分のスキルに合わせたコーディングをしていけばいいと思います。メモリ管理に興味があったら身近なところに実装例がありますよ(strbuf.cpp)。これが理解できれば動的メモリは怖くありません^^ -- kz3
- >スッキリまとまったサンプルを指しているのでしょうか
はい、スゴイなぁと。
strbuf.cpp見てみましたら、非常に難しいですね でも仰る通り、動的メモリを理解するには、一番のサンプルかもしれません。頑張ってみます
HDC を渡すのではなく HDC hdc = ( (BMSCR *)getbmscr( active_window ) )->hdc;
で、アクティブウィンドウに描画するという方法もあるのですね・・・ -- りさ
- 引数の参照渡しは関数呼び出し部を見ただけでは実引数に指定した変数が変更される可能性を読み取りにくいので注意しましょう。 -- naznyark?
- はい分かりました、ありがとうございます。少し変更してみますm(_ _)m戻り値は、関数・命令のどちらも必要なので、全てを参照渡しにするか、全てをポインタ渡し(?)にするかどっちかにしてみようと思います。それから、もうすこし実用的なサンプルにもしたいと思います(今のところ、処理内容は全く無意味ですし・・^^;) -- りさ
- ・・・色々やってみたのですが、動的メモリの参照渡しが出来ませんでした
SetBGColor関数は、active_windowのBMSCR構造体を取得して、hdc,sx,sy を参照する形にしてみました。
HSPのredraw 0 :color R,G,B :boxf と同じ機能になったと思います(^^ -- りさ
- > 動的メモリの参照渡しが出来ませんでした
BCC ではこれ↓でできましたが・・・。
+
| | テストソース
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
-
|
|
|
|
|
|
|
|
|
|
|
|
!
|
case 0x01:
return _ToLowerCase( pRef_retval );
int _ToLowerCase( void * & );
#include <windows.h>
#include "hsp3plugin.h"
int _ToLowerCase( void *&pRet )
{
char *strprm;
strprm = code_gets();
pRet = hspexpand( (char*)pRet, lstrlen( strprm ) + 1 );
lstrcpy( (char*)pRet, strprm );
CharLower( (char*)pRet );
return HSPVAR_FLAG_STR;
}
|
|
-- naznyark?
- あっ、引数は _ToLowerCase?(void *& ) なんですかぁ。ありがとうございますM(_ _)M 図を書いてやったりしたのですが、こんがらがる一方でした。 -- りさ
- int & : int型変数の参照を生成、void * & : void* 型変数の参照を生成、という感じです。 -- naznyark?
- 「参照を生成」でなく「参照として宣言」のほうが正しい表現でした。-- naznyark?
- なるほど、そうやって考えればいいんですね。型の形だけを考えればいいなんてスゴイ分かり易いです。とてもよく理解できました ありがとうございます! -- りさ
- SDKのサンプルを調べながらやったら、実数も変数も扱えるようになりました(多分^^;)naznyarkさん、kz3さん、どうもありがとうございます 残るわ・・システム変数に代入するくらい・・・でしょうか・・。これ以上、関数増やすとゴチャゴチャになってしまうような気がしますし。 -- りさ
- それと、chapter2.5なんて、勝手に作ってよかったのでしょうか?名前変えた方がいいでしょうか?? -- りさ
- CopyVariable? の基本はそれでいいんですが x と y の型が違う場合、また x が配列変数(の先頭の要素でない)場合は問題がありますよ。
それとその書式では x → y のコピー処理ではなく x ← y のコピー処理のほうが一般的のような・・・。 -- naznyark?
- 仰るとおりx←yが一般的のようでした(^^;;直してみます。x と y の型が違う場合
code_setva( pvalDest, aptrDest, type, pvalSrc->pt );
では、型が変えられないのでしょうか? その前に、
pvalDest->flag = type = pvalSrc->flag;
として、受け取り側の変数の型を変えておけばいいのですか? -- りさ
- すいません。code_setva は自動で型変換しますね。勘違いでした。-- naznyark?
- いえ、それより配列変数が渡された場合の問題とはなんなのでしょうか?
x = 3, 5
CopyVariable? x(1), y
とすると、x(1)の内容がyにちゃんとコピーされているようなんですけど・・・他に問題が起きる可能性があったりするのでしょうか? -- りさ
- ごめんなさい、kz3さんが、“連番でよかった”って言ってくれてました。すみません。今から連番に直せるのでしょうか? -- りさ
- >配列変数...
本当に正しく動いていますか?
1
2
3
4
5
|
| variable = 10000, 11111
CopyVariable variable(0), x
mes x
CopyVariable variable(1), x
mes x
|
それと DegToRad? では fmod を使ったり引数が負のときも考えた方が良いと思います。 -- naznyark?
- >本当に正しく動いていますか?
すみません、x←y の場合の配列xばかり考えていましたm(_ _)m反省してます
ご指摘頂いた通り、fmodを使って剰余を求め、負の場合は単純に360を加算して回避してみることにしました。
でも未だに配列要素が渡せないままです。
aptrポインタが配列要素の値を指していること、pval->pt が変数の値へのポインタであること、配列はこのアドレスから連続して確保されていることまで理解できました。色々やっているのですが、なかなか取得出来ない状態です。なんとか頑張ってみます! -- りさ
- 関数形式をサポートしているので、システム変数に関数値と同じ結果を代入するのは無意味だと思ったので、システム変数の部分を消しました。
pRef_retvalはstr型にしか使わないのでpRef_svalに変更してみました。出来たところまで、アップロードしておきます(^^ -- りさ
- 配列要素の実体ポインタはストレージコアファンクションを使用して取得するのが基本です。(仕様が公開されている型なら自前で算出することもできますが・・・)
PVal 構造体の offset メンバに対象要素の APTR 値を設定し、getproc 関数でその変数の型の HspVarProc? 構造体を取得して GetPtr? 関数を呼び出します。 -- naznyark?
- ありがとございます、もう少しゴニョゴニョやってみます! -- りさ
- getproc 関数というのは、hsp3plugin.h で getproc exinfo->HspFunc_getproc と定義されているのですね
- type = pvalSrc->flag;
pvalSrc->offset = 0;
HspVarProc? *hvp = getproc( type );
- ここまでは出来たのですが、GetPtr?関数を呼び出せません。ちゃんと定義されているはずなんですが・・(汗 -- りさ
- hvp->GetPtr?(pvalSrc)で出来ませんか?関数ポインタへの間接参照(呼び出し)ですよー。一通りできたらページをまとめる必要がありますね^^; -- kz3
- b9正式リリースはまだかなぁ -- kz3
- >hvp->GetPtr?(pvalSrc) 出来ました!! そして急いで関数ポインタの勉強を始めました
ホントにありがとうございます。今から載せますっ
- code_setva( pvalDest, aptrDest, type, hvp->GetPtr?(pvalSrc) ); とも書けますが、(あたしが)分かり易いように、一度 PDAT *型変数に代入しています。
- >をまとめる必要がありますね >ごちゃごちゃですよね(^^;;
>b9正式リリース >待ち遠しいですね。でも本音はHSP3.1が出て欲しいです^^/
- naznyarkさんとkz3さんのおかげで、HSPのことやプラグインのこと、そしてC言語のことなど、とても勉強になりましたM(_ _)M そしてHSP開発者のおにたまさんのスゴさを再実感しました(泣笑)
ところで実わ、HSPエディタを作って見ようと思って色々調べてみたのですが、今の実力では到底不可能なことを知りました(涙 コントロールだとかコンポーネントだとか・・・ 世界は広いですね
1
2
3
|
| if ( pval->flag == HSPVAR_FLAG_INT )
int val = *(int *)(pval->pt);
|
- 変数の値を取得する方法を載せなかったのですが、こんなカンジで大丈夫ですよね?
- 違いました(汗 よく考えたら、_CopyVariable?関数と同じようにすれば取得できますね
- どうやってまとめればいいのでしょう? とりあえず、『目標』の説明を増やしました。 -- りさ
- 余計かもしれませんが、main.cpp にも説明を加えました。 -- りさ
- そういえば hsp3plugin.cpp にHSPウィンドウのバッファ→実画面の画像コピー用関数( bms_send )が用意されていますよ。(私は使ったことないので忘れてました。) -- naznyark?
- そういえば、前に教わった気がしますっ!
bms_send(bm,0,0,bm->sx,bm->sy); で、画面を更新するものですよね。しかも試してみたら、redraw スイッチがオフのときは描画されないみたいです ってことは、描画系の命令(関数)には全部このようにした方がいいってことでしょうか??
処理の時間もスイッチの判定だけのような気がするので、小さいものだと思うのです。 -- りさ
- > 描画系の命令(関数)には全部このようにした方がいいってことでしょうか??
描画系命令・関数の処理の冒頭に判定をいれるのではなく BMSCR の hdc メンバのデバイスコンテキストに描画したあとに bms_send を呼び出すようにします。
こうすることで標準の描画系命令と同様の
redraw モードが 0 のときはバッファ画面への描画のみで実画面を更新しない。
redraw モードが 1 のときはバッファ画面へ描画して実画面も更新する。
という動作にすることができます。 -- naznyark?
- CountLetter?はメモリを確保するのにパラメータの文字列の長さを調べてるから、数えて確保してコピーして数えてって意味がないですね(笑)文字列パラメータをコピーする必要があるのは取得した文字列をほかで利用する場合なので文字列長を数えるくらいならコピーしなくても平気です。 -- kz3
- >という動作にすることができます。>> なるほど、つまりHSPの描画系の命令もこのようにして出来ているわけですねっ。さっそく変更してみました!動作もばっちりです
>文字列長を数えるくらいなら>>いえ、ほんとにそうですね(笑)なんかバカでした 数えて数えてしてました。直したらスゴクすっきりしました!
naznyarkさん、kz3さんどうもありがとうございますm(_ _)m-- りさ
- そういえばb9でましたネ -- りさ