Array classの使い方

[戻る]
horani 2010/12/08(水) 17:56:34
C++ CLRのプログラムを作っている初心者です。

Array クラスを使ったActiveXを呼び出そうとしたときにコンパイルエラーが出ます。
C#のサンプルコードが出ていて、C++でも同じように使おうとしていますが、うまくいき
ません。

私のC++ ソースコード (VC++2008対応)以下です。

宣言
    array<String^>^ StrTargetDnoAry ;
    array<String^>^ StrTargetValueAry ;

――――――Form_Load(System::Object^  sender, System::EventArgs^  e) {
     StrTargetDnoAry = gcnew array<String^>(16);
     StrTargetValueAry = gcnew array<String^>(16);
}

    private: System::Void Send_Click(System::Object^  sender, 
System::EventArgs^  e) {
。。。。。。。。。。。。。。省略
        StrTargetDno = String::Format("{0}",dnoact) ;
        StrTargetValue = "1" ;
        for(i = 0; i < 16 ; i++){
            StrTargetDnoAry[i] = String::Format("{0}",dnoact + 
i) ;
            StrTargetValueAry[i] = "1" ;
        }
        ret = this->axReadWriteOcx1->FuncWritePropartyMulti
(StrAmount, StrTargetDnoAry, StrTargetValueAry) ;

最後のactiveX呼び出し時にコンパイルエラーがこのように出ます。

error C2664: -------------::FuncWritePropartyMulti' : cannot convert parameter 
2 from 'cli::array<Type> ^' to 'System::Array ^%'
1>          with
1>          [
1>              Type=System::String ^
1>          ]


C#のサンプルコードはこうです。
     private void CmndWrite_Click(object sender, EventArgs e)
    {
        string[] StrTargetDno = new string[4];      //対象DNO
        Int32 lRet = 0;                             //関数戻り値
        string[] StrWriteData = new string[4];       //読み出しデータ
        Int32 IntCount = 0;
        if (TxtDno1.Text != "" && TxtWrite1.Text != "")
         {
            StrTargetDno[IntCount] = TxtDno1.Text;
            StrWriteData[IntCount] = TxtWrite1.Text;
            IntCount = IntCount + 1;
         }
。。。。。。。。。。。。。。
           Array AryDno = (Array)StrTargetDno;
           Array AryData = (Array)StrWriteData;
         lRet = axReadWriteOcx1.FuncWritePropartyMulti(ref IntCount, ref 
AryDno, ref AryData);
。。。。。。。。。。。。。。
}

要領を得なくてコードを短く出来なくて申し訳ありませんが、どなたかよろしくお願い
します。

horani 2010/12/08(水) 18:00:26
ret = this->axReadWriteOcx1->FuncWritePropartyMulti(StrAmount,StrTargetDnoAry, 
StrTargetValueAry) ;

Arrayの中のtypeあってないようですが、どうすればよいやら、
また、コンパイルメッセージの
from 'cli::array<Type> ^' to 'System::Array ^%'
にる^%'とはどういう意味でしょうか?

maru 2010/12/08(水) 18:59:29
CLRのプログラムは詳しくないのですが。。。

cli::arrayをSystem::Arrayに変換できないというエラーメッセージですね。
MSDNを見るとarray(全て小文字)とArray(先頭のみ大文字)があるようです。

>    array<String^>^ StrTargetDnoAry ;
>    array<String^>^ StrTargetValueAry ;
>     StrTargetDnoAry = gcnew array<String^>(16);
>     StrTargetValueAry = gcnew array<String^>(16);
のarrayをSystem::Arrayに置き換えたらどうなりますか?

Blue 2010/12/09(木) 10:07:10
単に参照で渡していないだけということでは?
C#のコードではrefが付いていますし。

>ret = this->axReadWriteOcx1->FuncWritePropartyMulti
>(StrAmount, StrTargetDnoAry, StrTargetValueAry) ;

ret = this->axReadWriteOcx1->FuncWritePropartyMulti
(StrAmount, %StrTargetDnoAry, %StrTargetValueAry) ;

Blue 2010/12/09(木) 11:48:56
ああ、よく見たら↑は間違ってますね。
忘れてください。

horani 2010/12/09(木) 14:16:08
もう一度整理のためにprogramを単純化しました。
驚いたことに、VisualStudio2010だと同様のerrorが出ましたが、
2008だとerrorが出ませんでした。
2010で何か癖があるんでしょうか?


private: System::Void button1_Click(System::Object^  sender, 
System::EventArgs^  e) {
    int num = 6 ;
     array<String^>^ strDno ;
     array<String^>^ strData ;
     strDno = gcnew array<String^>(5) ;
     strData = gcnew array<String^>(5) ;


    this->axReadWriteOcx1->FuncWritePropartyMulti(num,strDno,strData);
。。。。。。。

hirocco 2010/12/09(木) 17:58:45
FuncWritePropartyMultiのもともとの引数ってなんでしょう?

FuncWritePropartyMulti(ref Int32 a,ref Arrayb,ref Array c)
こんな感じかな?

hirocco 2010/12/09(木) 18:12:20
FuncWritePropartyMulti(ref Int32 a,ref Arrayb,ref Array c)
だとしたら
FuncWritePropartyMulti(StrAmount,(Array^)StrTargetDnoAry,(Array^)
StrTargetValueAry)でどうでしょうか?

horani 2010/12/10(金) 15:13:18
この引数は最初から、parameter guideでみると
int % ingPoint
cli::array<System::String^) ^strDno,cli::array<System::String^) ^% strDno
cli::array<System::String^) ^strDno,cli::array<System::String^) ^% strData
と表示されますね。
VS2010はこのガイドがstudioのバグで見れないようです。
arrayであっているように思います。
Arrayにすると定義の仕方から変わるようで、うまくいきまっせんね。

hirocco 2010/12/10(金) 19:23:11
えっと、例えばC#でDLLを作ってその中で
void Tatoeba1(ref Int32 a,ref Array b,ref Array c);
というのを作って、CLIで利用するときは
void Tatoeba1(int% a,System::Array^% b,System::Array^% c);
として利用しますね

また、C#でDLLを作ってその中で
void Tatoeba2(ref Int32 a,ref String[] b,ref String[] c);
というのを作ったならば、CLIで利用するときは
void Tatoeba2(int% a,cli::array<String^>^% b,cli::array<String^>^% c);
として利用します

でね、エラーの感じからすると
おそらく前者の
void Tatoeba(int% a,System::Array^% b,System::Array^% c);
なんだろうなって思います
でね、

cli::array<String^>^の型をSystem::Array^にキャストしてしまえばいいはずですよ
{
    int count    =16;
    cli::array<String^>^ a    =gcnew cli::array<String^>(0);
    cli::array<String^>^ b    =gcnew cli::array<String^>(0);

    for( int i=0;i<count;i++ )
    {
        System::Array::Resize( a,i+1 );
        System::Array::Resize( b,i+1 );

        a[a->length-1]    ="あいうえお";
        b[b->length-1]    ="かきくけこ";
    }
    System::Array^ aa    =static_cast<System::Array^>( a );
    System::Array^ bb    =static_cast<System::Array^>( b );

    Tatoeba1( count,aa,bb );
}
こんな感じかなぁ
どかな?

追記
^はハンドル型で、Cでいうところのポインタ
%はハンドル参照型で、Cでいうところの参照型を表す&ですよ

hirocco 2010/12/10(金) 19:25:31
追伸
System::Array^ a =gcnew System::Array(0)はできませんよ
抽象クラスですので

horani 2010/12/26(日) 22:56:05
ありがとうございます。
中国出張先でないと動作確認できないもので、、
先週まで別件を含めて、確認してきました。

^はハンドル型で、Cでいうところのポインタ
> %はハンドル参照型で、Cでいうところの参照型を表す&ですよ
コレ役に立ちました。
何のことがよくわからなかったですね。
C#とかいろいろ知らないと、できないこと多いですね。

どうも。Arrayでなく、arrayであっているようです。
現地のVCを2008に変更してうまくいきました。
VC2010は結局動作ができませんでしたね。
雰囲気的には、VC2010の安定感が低いような気がします。(素人の感^^)

ご返事が遅れて申し訳ありませんでした。
VC2010で動作しませんでしたが、良しとしたほうがよいようです。
2008では自動的castされるということなのかと思います。

horani 2010/12/26(日) 22:56:50
[[解決]]
ありがとうございました。
よいお年を、

古いスレッドには追加発言できません。