表題のような事は可能ですか?
今まで
exeファイルにコマンドプロンプトから次のように複数の引数を渡して使用していました。
例
C:\>test.exe "a" "b" "c" "d" "e" "f"
test.exeは次のように受け取りしてました。
int main(int argc, char *argv[])
{
// 省略
}
今回はこのtest.exeをActiveX化したいのです
VB6で
例
v(0) = "a":v(1) = "b":v(2)= "c" ・・・・・・・・
test.main(v(0))
と言うように配列を渡す事は可能でしょうか?
出来ない場合は別な方法を教えてください。
よろしくお願いします。
追伸
v= "a_b_c_d_e" '_は区切り文字
test.main(v)
が無難でしょうか
>今回はこのtest.exeをActiveX化したいのです
ということは COM になるわけですよね?(VBでは参照設定してNewして使う)
Declareで使えるようにするのは単なるDLLです。
どちらにせよ、文字列型配列ですのでSAFEARRAYを使うことになります。
ちなみに、文字型配列ですので,
>test.main(v(0))
のように先頭要素をByRefで渡すといらぬ変換(Unicode→Ascii変換)が起こりそうなので
配列全体をByRefで渡すような形にしたほうがいいです。
文字列型配列ではなくて、StrPtrの入ったLong型配列ならば簡単そうだけど。
>v= "a_b_c_d_e" '_は区切り文字
>test.main(v)
>が無難でしょうか
でしょうね。
Blue さん返事ありがとうございます。
DLLでは可能なのですね^^
書き忘れました、ごめんなさい。
OCXとして使用します。
アクティブXコンポーネントです。
よろしくお願いします。
>よろしくお願いします。
はSAFEARRAYを調べた上での発言なんでしょうか?
ActiveXは作ったことないですが、
v(0) = "a":v(1) = "b":v(2)= "c" ・・・・・・・・
test.main(v) ' ByRef s() As String
のような指定をして呼ぶ場合、C側では、LPSAFEARRAY* 型で受けることになります。
過去ログやWeb検索で一度 SAFEARRAY について検索してみるといいでしょう。
>SAFEARRAYを調べた上での発言なんでしょうか?
もちろん、調べつくしました。
VC++でActiveX コントロールを作成しているのですが
メソッドの追加から、引数のタイプを設定する項目に
LPSAFEARRAY*がありません。制約があるのかと思われます。
> LPSAFEARRAY*がありません。制約があるのかと思われます。
ではVARIANT*で受けてはどうでしょうか?
参考
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200609/06090040.txt
>VARIANT*で受けてはどうでしょうか?
質問する以前に参考を確認して色々と試しました。DLLでは可能でした。(MSDNにもありますよね)
ActiveX コントロールでは次の通りです。
ActiveX コントロールのVC++は
long CTestddCtrl::foo(VARIANT FAR* v)
{
SAFEARRAY* psa;
if ( v->vt != ( VT_ARRAY | VT_BSTR | VT_BYREF ) ) return 1;
psa = *( v->pparray );
if ( psa->cDims != 1 ) return 2;
return 0;
}
となっています。
VB6では
Private Sub Command1_Click()
Dim v(2) As String
v(0) = "こんにちわ"
v(1) = "テスト"
v(2) = "test"
MsgBox Testdd1.foo(v(0)) ←ここで型が一致しません
End Sub
次に
MsgBox Testdd1.foo(v) ←ここで型が一致しません
次に
Dim v(2) As Variant に変更した
MsgBox Testdd1.foo(v) ←ここで型が一致しません
次に
MsgBox Testdd1.foo(v(0)) メッセージボックスで”1”が表示
次にVC++の
// if ( v->vt != ( VT_ARRAY | VT_BSTR | VT_BYREF ) ) return 1;
として削除した。
MsgBox Testdd1.foo(v(0)) メッセージボックスで”2”が表示
以上まで確認しました。
適当にやってみた。
VC
void CActiveXTestCtrl::ShowList(VARIANT FAR* list)
{
// TODO: ここにディスパッチ ハンドラ コードを追加してください。
SAFEARRAY* psa;
BSTR wcs;
long i, lb, ub;
CString s;
if ( list->vt != ( VT_ARRAY | VT_BSTR ) ) return;
psa = list->parray;
if ( psa->cDims != 1 ) return;
SafeArrayLock( psa );
SafeArrayGetLBound( psa, 1u, &lb );
SafeArrayGetUBound( psa, 1u, &ub );
for ( i = lb; i <= ub; i++ )
{
SafeArrayGetElement( psa, &i, ( void* )&wcs );
AfxMessageBox( CString( wcs ) );
}
SafeArrayUnlock( psa );
}
VB
Option Explicit
Sub test()
Dim v As Variant
Dim s(2) As String
Dim a As New ActiveXTest
v = Split("ABC,あいう,a", ",")
a.ShowList v
s(0) = "漢字"
s(1) = "#%"
s(2) = "カタカナ"
v = s
a.ShowList v
End Sub
ActiveXならばBSTR*でもいけるようです。
VC
void CActiveXTestCtrl::ShowList2(BSTR FAR* list, long count)
{
// TODO: ここにディスパッチ ハンドラ コードを追加してください。
for ( int i = 0; i < count; i++ )
{
AfxMessageBox( CString( list[ i ] ) );
}
}
VB
Sub test()
Dim a As New ActiveXTest
Dim s(2) As String
s(0) = "おはよう"
s(1) = "こんにちは"
s(2) = "さようなら"
a.ShowList2 s(0), 3
End Sub
Blueさんありがとうございます。
Dim v As Variant ○
Dim v(4) As Variant ×
VB6の変数設定が悪かったのですね
勉強になりました。
よくよく考えてみたら、VARIANT*にする必要もなく、VARIANT型でよかったです。
それと、VB側でいちいち Variant型変数に入れなくてもString型配列渡せますね。
void CActiveXTestCtrl::ShowList(const VARIANT FAR& list)
{
// TODO: ここにディスパッチ ハンドラ コードを追加してください。
SAFEARRAY* psa;
BSTR wcs;
long i, lb, ub;
CString s;
if ( list.vt != ( VT_ARRAY | VT_BSTR ) ) return;
psa = list.parray;
if ( psa->cDims != 1 ) return;
SafeArrayLock( psa );
SafeArrayGetLBound( psa, 1u, &lb );
SafeArrayGetUBound( psa, 1u, &ub );
for ( i = lb; i <= ub; i++ )
{
SafeArrayGetElement( psa, &i, ( void* )&wcs );
AfxMessageBox( CString( wcs ) );
}
SafeArrayUnlock( psa );
}
Sub test()
Dim s(2) As String
Dim a As New ActiveXTest
s(0) = "漢字"
s(1) = "#%"
s(2) = "カタカナ"
a.ShowList s
End Sub
ツイート | ![]() |