2009-07-25 10 views
4

のために壊し最終更新日: 2009-08-11 14:30 EDTはVB6アプリ

数日前、私はいくつかの非常に奇妙な問題についてthis questionを掲載しました。さて、あるマシンをビルドさせて他のマシンを動かさないようにしていたのはわかっていて、回避策も出てきましたが、今は素敵な具体的な質問が残っています。

問題を再現するために、私は新しいInteropUserControlを作成し、次の操作を行います

  1. public struct MyStruct新しい追加:それをGUIDとComVisible属性
  2. を与える
  3. _InteropUserControlGetMyStructメンバーを追加します。インターフェイスを実装し、InteropUserControlに実装します。

MyStruct

[Guid("49E803EC-BED9-4a08-B42B-E0499864A169")] 
[ComVisible(true)] 
public struct MyStruct { 
    public int mynumber; 
} 

_InteropUserControl.GetMyStruct()

[DispId(7)] 
void getMyStruct(int num, ref MyStruct data); 

(Iも同様に、MyStructを返す代わりに、参照によって通過しようとしている。)

InteropUserControl.GetMyStruct()実装:

public void getMyStruct(int num, ref MyStruct data) { 
    data = new MyStruct(); 
    data.mynumber = num * 2; 
} 

また、アセンブリに署名してGACにインストールし、Regasmで登録します。新しいVB6プロジェクトに追加してGetMyStruct()への呼び出しを追加し、ビルドマシンでコンパイルすると、他のマシンでの実行を拒否します。この問題を回避するには

は、私が代わりに構造体のCOMにクラスを公開しなければならなかった、と基本的にはこれにGetMyStructを変更します。私の実際のプロジェクトで

public void GetMyData(int num, MyClass data) { 
    data.mynumber = num * 2; 
} 

、私は内部構造体を取得した後、コピー構造体からクラスのインスタンス上の一致するメンバーまでのすべてのフィールド値は、クライアントによってメソッドに渡されます。

なぜ構造体がこの動作を引き起こし、クラスが正常に動作しましたか? VB6で使用するためにCOMに構造体を公開するにはいくつかの魔法がありますか?

私はそれがOLEオートメーションと関係があるかもしれないと思います。

注:refパラメータを使用するのではなく、構造体を返そうとしましたが、動作を変更しませんでした。

編集テンプレートを投影するリンクを追加するには:

Interop Forms Toolkit 2.0は、元のVB.NETのプロジェクトテンプレートおよびDLLです。私はdllを参照しないので、これをインストールする必要はありません。

C# Translations of templates on CodeProject私が作成したものです(プロジェクトテンプレートで、アイテムテンプレートではありません)。 VB。NETバージョンは、__InteropUserControlイベントインターフェイス、_InteropUserControlインターフェイス、およびいくつかの関連する属性を自動的に生成します。これらはC#バージョンで明示的にコード化されています。

+1

getMyStructでは、msとは何ですか?データでなければならないのでしょうか? – SwDevMan81

+1

短いが、_complete_複製を提供できますか? – AnthonyWJones

+0

@ SwDevMan81:そうです。私の一部にはタイプミス。それは1秒で修正されます。 –

答えて

2

私はこの問題の解決策を見つけたと思います。 構造体を渡してinteropライブラリのメソッドを呼び出すときに、同じ問題が発生しました。これはDLLの相互運用性をテストするために作成したプロジェクトなので、私がプロジェクトで持っているのはフォームでした。しかし、同じリファレンスを持つ別のプロジェクト(メインアプリケーション)があり、正常に動作します。

ジョエルのポストを読んだ後、私は彼のソリューションをテストしたいと思っていました。実際にはidが機能しました(代わりにクラスを使用しています)。しかし、私は構造体を使用しているところで他のインタープロセッサーを持っているので、いつでもアプリケーションが失敗するかもしれないと心配していました。また、構造体を置き換えるインタフェースとクラスを作成して公開する余分な作業をしたくありませんでした。

私は自分のフォームからコードを取り出し、それをモジュール内のパブリックサブに移動しました。それはすぐに働いた。ちなみに、それは私がokで動作していたメインアプリケーションで呼び出しを実装した方法です。

他人に役立つことを願っています。

+0

私はこのようなテストプロジェクトをもう一度設定し、VB6のモジュールから呼び出す必要があります。残念ながら、メインのinteropオブジェクトはフォーム上に存在しなければならないコントロール(ビジュアルディスプレイ)であるため、これは私のアプリケーションでは役に立ちません。しかし、これは非常に興味深い情報です。 –

+0

私は先に進み、あなたの答えに合格とマークを付けることに決めました。私の場合、呼び出しコードをモジュールに移動することはできませんでしたが、2つのソリューションのうちの1つのようです。 –

1

VB6で使用するために 構造体をCOMに公開するには、いくつかの魔法がありますか?

MSDNの記事COM Data Types *は、構造体をサポートしていることを述べています。記事のカップルは、ページの一番下にあなたのCOM呼び出し可能ラッパーをcustomingにもありますが、あなたがそれらを検討したいと思うかもしれ

ByRef VALUETYPE<MyStruct> 

:具体的には、MSDNの記事は、COM構造は次のように定義されていることを述べています。

  • 編集(2016):元のリンクが壊れていたため、.NET Frameworkのバージョン3.5に修正しました。
+0

+1:私は試していただきありがとうございます。私は彼らが働くことになっていることを知っています(そして、ある程度、彼らはします)。私はまた、特に 'MarshalAsAttribute'でいくつかのカスタマイズを試みましたが、私が記述した振る舞いを変更したものはありません。興味深い。 –