C++(.Net) と C# DLL にアクセスする


この章では、Origin CでC++(.Net) や C# から作成されたDLLにアクセスする方法を紹介しています。

C# クラス DLL にアクセスする

Microsoft Visual Studio 2005 でC#のDLLを作成し、Origin Cでそれにアクセスする方法を紹介しています。このDLLは、プロパティと関数をクラスに提供するものです。関数Sumは、Origin CベクトルからC#関数にデータ配列を渡す方法を示しています。

  1. Microsoft Visual Studio 2005で、メニューからファイル -> 新規 -> プロジェクト...を選択し、新しいプロジェクトダイアログで、 次のように設定を選択してください。
    Ocguide externaldll csharp1 newproject.png
  2. 次のコードをcsファイルにコピーします。
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace temp
    {
        [Guid("4A5BFDFA-7D41-49d1-BB57-C6816E9EDC87")]
        public interface INet_Temp
        {
            double Celsius{ get; set; }
            double Fahrenheit{ get; set; }
     
            double GetCelsius();
            double GetFahrenheit();
    
            double Sum(object obj);
        }
    }
    
    namespace temp
    {
        [Guid("2AE913C6-795F-49cc-B8DF-FAF7FBA49538")]
        public class NET_Temperature : INet_Temp
        {
            private double celsius;
            private double fahrenheit;
    
            public NET_Temperature()
            {
            }
    
            public double Celsius
            {
                get{ return celsius; }
                set { celsius = value; fahrenheit = celsius + 273.5;  }
            }
            public double Fahrenheit
            {
                get { return fahrenheit; }
                set { fahrenheit = value; celsius = fahrenheit - 273.5; }
            }
    
            public double GetCelsius()
            {
                return celsius;
            }
            public double GetFahrenheit()
            {
                return fahrenheit;
            }      
    
            public double Sum(object obj)
            {
                double[] arr = (double[])obj;
                double sum = 0.0;
                for (int nn = 0; nn < arr.Length; nn++)
                {
                    sum += arr[nn];
                }
                return sum;
            } 
        }
    }
  3. メニューから、ツール -> GUIDの作成 を選択して、開いたダイアログで Registry Format を選択して New GUID をクリックし、Copyボタンをクリックします。このGUIDを貼り付けて、上述のコードの[Guid("...")] 内のものを削除します。コード内の2番目のGUIDを置き換えるためには、このアクションを再度行います。
  4. プロジェクト上で右クリックして、プロパティを選択し、プロパティページを開きます。そして、アセンブリをCOM参照可能にするのチェックボックスにチェックを付けます。32 bit版の場合、ビルドタブを開き、COM相互運用機能の登録のチェックボックスをチェックします。64 bit版の場合、ビルドイベントタブを開き、次のコマンドラインをコピーしてビルド前に実行するコマンドラインテキストボックスに貼り付けます。F6キーを押してソリューションをビルドします。
  5. "%Windir%\Microsoft.NET\Framework64\v4.0.30319\regasm" "$(TargetPath)" /CodeBase
  6. Originを開き、コードビルダを開いて、新しいCファイルに次のOrigin Cコードをコピーします。
    void access_DLL()
    {
    	Object obj = CreateObject("temp.NET_Temperature");
    	
    	obj.Celsius = 0; // プロパティにアクセス
    	out_double("", obj.GetFahrenheit()); // 関数にアクセス
    	
    	obj.Fahrenheit = 300;
    	out_double("", obj.GetCelsius());
    
    	vector vec;
    	vec.Data(1,10,1);
    	_VARIANT var = vec.GetAs1DArray();
    	out_double("", obj.Sum(var));
    }

C# と C++ リソースDLLにアクセスする

C#によるActiveXコントロールを作成し、Origin C内のダイアログで使用する方法を示しています。

ステップ1~7では、C# ActiveX コントロールを Microsoft Visual Studio 2005 で作成する方法を示しています。

  1. Microsoft Visual Studio 2005を起動し、メニューからファイル -> 新規 -> プロジェクト... を選択して、新しいプロジェクトダイアログを開きます。そして、次のように設定してOKボタンをクリックします。
    Ocguide externaldll csharp2 newproject.png
  2. UserControl.cs ファイルに次のコードをコピーしてprotected override functionを追加し、色塗りの制御とpublic functionを追加して境界の制御をします。
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Data;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace SampleControl
    {
        [Guid("A31FE123-FD5C-41a1-9102-D25EBD5FDFAF"),
        ComSourceInterfaces(typeof(UserEvents)),
        ClassInterface(ClassInterfaceType.None),]
        public partial class UserControl1 : UserControl, UserControl1Interface
        {
            public UserControl1()
            {
                InitializeComponent();
            }
    
            protected override void OnPaint(PaintEventArgs pe)
            {
                Brush brush = new SolidBrush(Color.Beige);
    
                pe.Graphics.FillRectangle(brush, ClientRectangle);
            }
    
            public void SetBorder(bool bSet)
            {
                this.BorderStyle = bSet ?BorderStyle.FixedSingle :
                            BorderStyle.None;
                Refresh();
            }
        }
    
        //設定制御のためのインターフェースを宣言
        [Guid("CCBD6133-813D-4dbb-BB91-16E3EFAE66B0")]
        public interface UserControl1Interface
        {
            void SetBorder(bool bSet);
        }
    }
  3. メニューからツール -> GUIDの作成を選択して、GUIDの作成ダイアログを開き、Registry Formatラジオボタンを選択します。New GUID と Copy ボタンをクリックして新しく作成されたGUIDをコピーします。新しいGUIDを使用して上述のコード[Guid("...")] 内のものと置き換えます。
  4. UserControl1.cs[Design] タブを選択し、プロパティウィンドウでイベントボタンOcguide externaldll csharp2 eventbutton.png をクリックし、スクロールバーをドラッグして MouseClick をダブルクリックしてマウスクリックイベント関数をUserControl.cs ファイルに追加します。同じ方法で、マウスダブルクリックイベントを追加します。
  5. UserControl1l.cs ファイルでは、UserControl1 クラス外部に次のコードをコピーします。
    //イベントのためのデリゲートを宣言 
    public delegate void MouseAction(int x, int y);
  6. UserControl1 クラスで、次のインプリメントを追加します。
    public event MouseAction OnUserClick;
    public event MouseAction OnUserDbClick;
    
    private void UserControl1_MouseClick(object sender, MouseEventArgs e)
    {
          if (OnUserClick != null)
          {
              OnUserClick(e.X, e.Y);
          }
    }
    
    private void UserControl1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
          if (OnUserDbClick != null)
          {
              OnUserDbClick(e.X, e.Y);
          }
    }
  7. UserControl1 クラス外部で、次のインターフェースを追加します。
    //イベントのためのインターフェースを宣言
    
    [Guid("DA090A6F-FFAC-4a39-ACD3-351FA509CA86"), 
        InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface UserEvents
    {
        [DispIdAttribute(0x60020001)]
        void OnUserClick(int x, int y);
    
        [DispIdAttribute(0x60020002)]
        void OnUserDbClick(int x, int y);
    }
  8. Visual Studio 2008 でリソースのみのDLLを作成する方法は、ダイアログビルダ:単純なHello Worldダイアログ:Visual Studio 2008 でリソースのみのDLLを作成する を参照してください。
  9. Origin Cによって、ダイアログでActiveXコントロールを使用し、表示します。Originのコードビルダで、cファイルを作成し、次のコードをコピーします。
    //ダイアログとIdsのコントロール。実際の利用に応じてダイアログidは変更する必要がある。
    #define IDD_DIALOG1                     101
    #define IDC_DOTNET						1000
    
    //コントロールから公開されたイベント
    #define	ON_INTEROP_CLICK(_idCntl, _ocFunc)	
    ON_ACTIVEX_EVENT(0x60020001, _idCntl, _ocFunc, VTS_CTRL VTS_I4 VTS_I4)
    
    #define	ON_INTEROP_DBLCLICK(_idCntl, _ocFunc)	
    ON_ACTIVEX_EVENT(0x60020002, _idCntl, _ocFunc, VTS_CTRL VTS_I4 VTS_I4)
    
    
    class CDotNetComInteropDlg : public Dialog
    {
    public:
    	CDotNetComInteropDlg();
    
    	EVENTS_BEGIN
    	ON_INIT(OnInitDialog) 
    	//公開されたイベントのためのイベントハンドラ
    	ON_INTEROP_CLICK(IDC_DOTNET, OnClick)
    	ON_INTEROP_DBLCLICK(IDC_DOTNET, OnDblClick)
    	EVENTS_END
    	
    	BOOL OnClick(Control ctrl, int x, int y)
    	{
    		printf("Clicked at (%d,%d)\n", x,y);
    		return true;
    	}
    	
    	BOOL OnDblClick(Control ctrl, int x, int y)
    	{
    		printf("DblClicked at (%d,%d)\n", x,y);
    		return true;
    	}
    
    	
    	BOOL OnInitDialog();
    	
    	Control m_ctrlDotNet;
    };
    
    
    // ここではDLLファイルのパスを指定しない。DLLファイルは  
    //現在のcファイルと同じパスにあると仮定
    CDotNetComInteropDlg::CDotNetComInteropDlg()
    	: Dialog(IDD_DIALOG1, "DialogBuilder.dll")
    {
    	InitMsgMap();
    }
    
    
    BOOL CDotNetComInteropDlg::OnInitDialog()
    {	
    	//[Guid("A31FE123-FD5C-41a1-9102-D25EBD5FDFAF")]
    	GUID guid = {0xA31FE123, 0xFD5C, 0x41a1, 
    		{0x91, 0x02, 0xD2, 0x5E, 0xBD, 0x5F, 0xDF, 0xAF}};
    	
    	RECT rect = {20,20,200,100};
    	if(m_ctrlDotNet.CreateActiveXControl(guid, WS_CHILD|WS_VISIBLE,
    		rect, GetSafeHwnd(), IDC_DOTNET))
    	{
    		//DotNet コントロールのインターフェースを使用して 
    		//初期化をコントロール
    		Object ctrlObj = m_ctrlDotNet.GetActiveXControl();
    		ctrlObj.SetBorder(true);
    	}
    	return TRUE;
    }
    
    void Launch_CDotNetComInteropDlg()
    {
    	CDotNetComInteropDlg dlgDotNet;
    	dlgDotNet.DoModal();
    }