- PR -

[C#]ActiveX DLLのメソッドの返値がobject型でキャストできません・・・

投稿者投稿内容
ひでと
会議室デビュー日: 2005/06/11
投稿数: 5
投稿日時: 2005-06-11 21:22
はじめまして、初心者でくだらない質問かもしれません。

 C#でActiveX DLLを利用しようと思い参照の追加を行い、殆どのプロパティやメソッドは問題なく利用することができました。

 ところがあるメソッドについて問題が出てきました。説明書によるとそのメソッドの返り値はDLL内の別のオブジェクトを取得するというような事でした。オブジェクトブラウザで見るとSystem.Object型となっていたのですが、参照の追加を行った際にそのオブジェクトも確認できたので、型キャストしようとしたのですが実行すると「指定したキャストは有効ではありません」とエラーが出ます。

 その「別のオブジェクト」内のメソッドを利用したかったのですが、ここでつまづいて先に進めなくなってしまいました。

 初心者でうまく説明できなくて申し訳ありませんが、どなたか解決方法を教えて頂けないでしょうか?よろしくお願いします。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2005-06-11 21:40
引用:

 ところがあるメソッドについて問題が出てきました。説明書によるとそのメソッドの返り値はDLL内の別のオブジェクトを取得するというような事でした。オブジェクトブラウザで見るとSystem.Object型となっていたのですが、参照の追加を行った際にそのオブジェクトも確認できたので、型キャストしようとしたのですが実行すると「指定したキャストは有効ではありません」とエラーが出ます。



どんな型にキャストしようとしましたか?

「参照設定」によって自動生成される Hoge 型や HogeClass 型ではなく、IHoge 型=目的のオブジェクトが実装しているインターフェース型でキャストしてみては?


_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2005-06-11 21:46
引用:

 その「別のオブジェクト」内のメソッドを利用したかったのですが、ここでつまづいて先に進めなくなってしまいました。



ラッパーソースの中に『その「別のオブジェクト」』の型定義とか
インタフェースの定義とかがありませんでしたか?

_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2005-06-12 10:47
unibon です。こんにちわ。

引用:

未記入さんの書き込み (2005-06-11 21:22) より:
 その「別のオブジェクト」内のメソッドを利用したかったのですが、ここでつまづいて先に進めなくなってしまいました。


もしかしたら、その「別のオブジェクト」が別のDLL/OCXになっている場合もあります。そういう時はそれを別途、参照設定しないといけないのかもしれません。
また、デバッガでウォッチしてみると、実行時に返される型の名前は分かったと思いますので、それを頼りに正しいクラス名を見つけることができるみたいです。「説明書」とかは結構アテにならない(か分かりにくく書いてある)ことも多いです。(仕様の取り決めは事前に分かっているのが理想なのでしょうが、)実際に動かした時の情報から辿って行くほうが確実です。
ひでと
会議室デビュー日: 2005/06/11
投稿数: 5
投稿日時: 2005-06-12 12:18
色々とご返事有難うございます。大変感謝しています。

unibon 様

別のDLL/OCXかもということですが、参照の追加で選択したものが「????.tlB」というファイルでしたので、元々どのDLLなのかすらよくわかっていません。申し訳ないです。

Jubei 様、渋木宏明(ひどり) 様

 インターフェース型でキャストは試していなかったので、早速試してみたいと思います。ただインターフェース型らしきものが幾つかありどれが良いのかよくわからないので何度かやってみます。

結果はまたご報告に伺いたいとおもいます。本当に有難うございました。
ひでと
会議室デビュー日: 2005/06/11
投稿数: 5
投稿日時: 2005-06-12 17:01
 ご指摘のようにインターフェース型に変更したところエラーも出ず、無事に別オブジェクト内のメソッドを扱うことができるようになりました。
本当に有難うございました。
 
 ところで、実際にそのメソッドを使用する際に、引数としてバリアント型を渡して(内部的には単精度浮動小数点の1次元配列です)そのなかに計算結果等が返ってくるようになっているものがあります(C#で追加した際にバリアント型はobject型に変更されていました)。
 ここに、System.Single[] ArrayData;ArryData = new Single[100]というように配列を確保して引数に渡したのですが、値は何も変わらず全て0のままになってしまいます。メソッドの返数では計算結果の配列サイズを返しているので処理自体はは行っているようです。
 キャスト、もしくは型宣言などどこかに悪い点があるのでしょうか?

 新規スレッドにするべきなのかもしれませんが、同じobject型ついてでしたので続けさせて頂きました。

 知らない事が多く、度々すみませんがどうぞよろしくお願いします。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2005-06-12 17:33
引用:

 キャスト、もしくは型宣言などどこかに悪い点があるのでしょうか?



おそらく ActiveX DLL の問題です。
コードではなく、型情報の記述にミスがある印象を強く受けます。

引数で渡した配列が変更されて返って来るようなメソッド呼び出しは、C# では

Hoge(ref object array);

のような形式になります。

ですが、「参照設定」しても

Hoge(object array);

のような形式のメソッドが生成されているなら、それは ActiveX DLL の型情報の記述が不適切だからです。(メソッドの動作を正しく伝えていない)

ActiveX DLL を修正して「参照設定」し直すのが正しい対応です。


[ メッセージ編集済み 編集者: 渋木宏明(ひどり) 編集日時 2005-06-12 17:34 ]
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2005-06-12 18:11
引用:

渋木宏明(ひどり)さんの書き込み (2005-06-12 17:33) より:
引数で渡した配列が変更されて返って来るようなメソッド呼び出しは、C# では

Hoge(ref object array);

のような形式になります。


配列をマーシャラに渡して、その中身が書き換えられる場合は、
refではなくSystem.Runtime.InteropServices.OutAttribute属性ではないですかね?

スキルアップ/キャリアアップ(JOB@IT)