none
System.__ComObjectとdynamic RRS feed

  • 質問

  • いつもお世話になっております。

    VS2015UD2で作業しています。

    今回はc++32ビットActiveXコントロールを64ビットにコンパイル→C#にて貼り付け(AxHost使用)→そのコントロールになにかデータ渡すを行っております。

    C#については全く基礎のない状態で何とかできそうな方向性を見るべく取かかっているのですが(一回だけお絵かきアプリのサンプルを見ながら流れを確認しただけです)、
    dllなどの連絡や、変数の定義、オブジェクトの生成などとりあえずのFormの表示は出来ているようなのですが、

    下記のような形で、

    axView1.hoge = hg;

    としたいところの値を渡す作業が全くできず理解不能な状態です。

    hgはSystem.__ComObjectとなり、

    axView1.hogeは下記Cv参照からdynamicです。

    dynamicへは基本的にキャストなく渡せるはずと思っているのですが、何か間違っているのだと思います。

    どうかご教示くださいませ。どうぞ宜しくお願いいたします。

    尚、AxHostはAximp.exeで作りました。

    - IViewメタデータ -
    namespace Cv
    {
        public interface IView
        {
            dynamic hoge { get; set; }
        }
    }
    
    
    
    - Form1.Designer.cs -
    namespace onCSharp
    {
        partial class Form1
        {
            private void InitializeComponent()
            {
                this.axView1 = new AxCv.AxView();
                this.panel1 = new System.Windows.Forms.Panel();
    
                ((System.ComponentModel.ISupportInitialize)(this.axView1)).BeginInit();
                this.panel1.SuspendLayout();
                this.SuspendLayout();
    
                // 
                // axView1
                // 
                this.axView1.Enabled = true;
                this.axView1.Location = new System.Drawing.Point(0, 0);
                this.axView1.Name = "axView1";
                this.axView1.TabIndex = 0;
                this.axView1.Dock = System.Windows.Forms.DockStyle.Fill;
                // 
                // panel1
                // 
                this.panel1.Location = new System.Drawing.Point(38, 58);
                this.panel1.Name = "panel1";
                this.panel1.Size = new System.Drawing.Size(200, 100);
                this.panel1.TabIndex = 0;
                this.panel1.Controls.Add(this.axView1);
                // 
                // Form1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(284, 261);
                this.Controls.Add(this.panel1);
                this.Name = "Form1";
                this.Text = "Form1";
                this.Load += new System.EventHandler(this.Form1_Load);
    
                ((System.ComponentModel.ISupportInitialize)(this.axView1)).EndInit();
                this.panel1.ResumeLayout(false);
                this.panel1.PerformLayout();
                this.ResumeLayout(false);
            }
    
            private AxCv.AxView axView1;
        }
    
    }
    
    
    
    - Form1.cs -
    namespace onCSharp
    {
        public partial class Form1 : Form
        {
            Bv.app app;
            Bv.hoge hg;
    
            public Form1()
            {
                InitializeComponent();
    
                app = new Bv.app();
                app.BeginInit();
                app.EndInit();
    
                //hg = new B.hoge();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                hg = app.data("C:\\75.data");
                
                if ((hg as Bv.hoge) != null)
                    MessageBox.Show("ok");
    
                axView1.hoge = hg;
    
                if ( ((Bv.hoge)axView1.hoge) != null)
                    Console.WriteLine("yesssss");
                else
                    Console.WriteLine("nooooooo");
            }
        }
    }
    
    
    
    - AxCv.cs -
    namespace AxCv {
      public class AxView : System.Windows.Forms.AxHost {
          private Cv.IView ocx;
          
          private AxViewEventMulticaster eventMulticaster;
          
          private System.Windows.Forms.AxHost.ConnectionPointCookie cookie;
          
          public AxView() : 
                  base("*-*-*-*-*") {
          }
    
    
          [System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
          [System.Runtime.InteropServices.DispIdAttribute(1)]
          public virtual object hoge {
              get {
                  if ((this.ocx == null)) {
                      throw new System.Windows.Forms.AxHost.InvalidActiveXStateException("hoge", System.Windows.Forms.AxHost.ActiveXInvokeKind.PropertyGet);
                  }
                  return this.ocx.hoge;
              }
              set {
                  if ((this.ocx == null)) {
                      throw new System.Windows.Forms.AxHost.InvalidActiveXStateException("hoge", System.Windows.Forms.AxHost.ActiveXInvokeKind.PropertySet);
                  }
                  this.ocx.hoge = value;//////////////////////<<<<<<<<<<<<<<<------- this.ocx.hogeがずっとnullのまま
              }
          }
      }
    }

    2016年7月12日 7:50

回答

  • 自己レスです。

    以下と同義ではないかということで、終了します。
    https://social.msdn.microsoft.com/Forums/ja-JP/7a071803-641e-4c09-8821-162e37313539/cactivex?forum=csharpgeneralja

    ありがとうございました。

    • 回答としてマーク 星 睦美 2016年9月15日 6:57
    2016年8月9日 8:25

すべての返信

  • > private Cv.IView ocx;
    > this.ocx.hogeがずっとnullのまま

    ocx フィールドに何のインスタンスもセットしていないように見受けられます。

    良くある実装としては、AxHost.AttachInterfaces メソッド をオーバーライドして、

    this.ocx = (Cv.IView)base.GetOcx();
    などとする事が多いです…が、それが求める答えであるかどうかは判断致しかねます。

    2016年7月12日 10:00
  • 魔界の仮面弁士 様

    レスありがとうございました。

    上のコードに入れていませんでしたが、aximp.exeが生成したものの中に既におっしゃられたようなものがございました。
    InitializeComponent()の((System.ComponentModel.ISupportInitialize)(this.axView1)).EndInit();あたりで飛んでくるようです。

    c++ActiveXコントロール側では、VT_DISPATCHで受け取りたいことが分かり、

    axView1.hoge = hg;

    axView1.hoge = new DispatchWrapper(hg);
    としてみましたが現象変わらずでした。

    宜しくお願いいたします。

    - AxCv.cs -
    namespace AxCv {
      public class AxView : System.Windows.Forms.AxHost {
    ....
    ....
            protected override void AttachInterfaces() {
                try {
                    this.ocx = ((Cv.IView)(this.GetOcx()));
                }
                catch (System.Exception ) {
                }
            }
    ....
    ....
    }



    • 編集済み SHIN109 2016年7月13日 9:13 追記
    2016年7月13日 0:09
  • 自己レスです。

    その後、Releaseモードで実行してみると値が渡されていることが確認できました。
    axView1.hoge = hg;のままでも大丈夫でした。

    しかしDebugモードの場合には、同じくnullで、見た目のViewに変化がないのは、動作が64ビットとデザイン(IDE)が32ビットの関係でしょうか?

    宜しくお願いいたします。
    2016年7月14日 8:14
  • 自己レスです。

    以下と同義ではないかということで、終了します。
    https://social.msdn.microsoft.com/Forums/ja-JP/7a071803-641e-4c09-8821-162e37313539/cactivex?forum=csharpgeneralja

    ありがとうございました。

    • 回答としてマーク 星 睦美 2016年9月15日 6:57
    2016年8月9日 8:25