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);
。。。。。。。。。。。。。。
}
要領を得なくてコードを短く出来なくて申し訳ありませんが、どなたかよろしくお願い
します。
ret = this->axReadWriteOcx1->FuncWritePropartyMulti(StrAmount,StrTargetDnoAry,
StrTargetValueAry) ;
Arrayの中のtypeあってないようですが、どうすればよいやら、
また、コンパイルメッセージの
from 'cli::array<Type> ^' to 'System::Array ^%'
にる^%'とはどういう意味でしょうか?
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に置き換えたらどうなりますか?
単に参照で渡していないだけということでは?
C#のコードではrefが付いていますし。
>ret = this->axReadWriteOcx1->FuncWritePropartyMulti
>(StrAmount, StrTargetDnoAry, StrTargetValueAry) ;
ret = this->axReadWriteOcx1->FuncWritePropartyMulti
(StrAmount, %StrTargetDnoAry, %StrTargetValueAry) ;
ああ、よく見たら↑は間違ってますね。
忘れてください。
もう一度整理のために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);
。。。。。。。
FuncWritePropartyMultiのもともとの引数ってなんでしょう?
FuncWritePropartyMulti(ref Int32 a,ref Arrayb,ref Array c)
こんな感じかな?
FuncWritePropartyMulti(ref Int32 a,ref Arrayb,ref Array c)
だとしたら
FuncWritePropartyMulti(StrAmount,(Array^)StrTargetDnoAry,(Array^)
StrTargetValueAry)でどうでしょうか?
この引数は最初から、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にすると定義の仕方から変わるようで、うまくいきまっせんね。
えっと、例えば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でいうところの参照型を表す&ですよ
追伸
System::Array^ a =gcnew System::Array(0)はできませんよ
抽象クラスですので
ありがとうございます。
中国出張先でないと動作確認できないもので、、
先週まで別件を含めて、確認してきました。
^はハンドル型で、Cでいうところのポインタ
> %はハンドル参照型で、Cでいうところの参照型を表す&ですよ
コレ役に立ちました。
何のことがよくわからなかったですね。
C#とかいろいろ知らないと、できないこと多いですね。
どうも。Arrayでなく、arrayであっているようです。
現地のVCを2008に変更してうまくいきました。
VC2010は結局動作ができませんでしたね。
雰囲気的には、VC2010の安定感が低いような気がします。(素人の感^^)
ご返事が遅れて申し訳ありませんでした。
VC2010で動作しませんでしたが、良しとしたほうがよいようです。
2008では自動的castされるということなのかと思います。
ありがとうございました。
よいお年を、