C#で作ったマネージクラス(COM)をC++から呼び出す

naohiro19
記事: 256
登録日時: 14年前
住所: 愛知県

C#で作ったマネージクラス(COM)をC++から呼び出す

投稿記事 by naohiro19 » 9年前

C#のプロジェクト名は「Sample」として作成します。Cドライブ直下にプロジェクトを作成します。
C#のメソッドをC++で呼ぶにはC#側をCOM参照可能にすれば呼び出すことができます。

Class1.csは以下の内容となっています。

CODE:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace Sample
{
// [ComVisible(true)]
    public interface ICalc
    {
        int Add(int x, int y);
    }

    [ClassInterface(ClassInterfaceType.None)]
    public class Calc : ICalc
    {
        public int Add(int x, int y)
        {
            return x + y;
        }

    }
}
► スポイラーを表示
ソリューションエクスプローラーから太字になっている「Sample」を右クリックして「プロパティ」を選びます。
「アプリケーション」の「アセンブリ情報」から「アセンブリをCOM参照可能にする」にチェックを入れ、「ビルドタブ」をクリックして「COM相互運用機能の登録」にチェックを入れます。
ビルドしてDllが生成されます。
「OLE+COM Object Viewer」でInterface欄に「ICalc」が表示されているかチェックします。ICalcを消すにはpublic interface と書かれた[ComVisible(true)]という行を[ComVisible(false)]に変えればOKです。

Visual Studio のVisual C++のプロジェクトから「Win32 コンソール」を選んでプロジェクトを作成します。このときATLにチェックを入れておきます。
タイプライブラリ(*.tlb)をプロジェクトに配置します。
Addを呼び出すには以下のプログラムを書いてビルドすれば呼び出せます。

CODE:

// CallCpp.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#import "Sample.tlb" no_namespace named_guids

int _tmain(int argc, _TCHAR* argv[])
{
	CoInitialize(NULL);
	{
		CComPtr pObj;
		HRESULT hr = pObj.CoCreateInstance(__uuidof(Calc));
		ATLASSERT(hr == S_OK);
		int ret = pObj->Add(1, 3);
		printf("result %d\n", ret);
	}
	CoUninitialize();
	return 0;
}
コンソール画面に
result 4
と表示されていたらC#のクラスライブラリは呼び出されています。ATL版ではCoInitializeとCoUninitializeの間に中括弧をつけているのはReleaseが自動的に呼ばれるようにしています。
中括弧なしでCoUninitializeを呼び出すと正しくReleaseが呼ばれない可能性があるのでメモリリークの可能性があるからです。

regasmとgacutilを使わない呼び出し方法についてはマネージドDLLとの接続、ActiveX(COM)による接続、アンマネージドDLLとの接続というサイトをご覧ください。

さらにおまけでSample.tlhとSample.tliの中身です。
► スポイラーを表示
最後に編集したユーザー naohiro19 on 2015年9月04日(金) 22:38 [ 編集 11 回目 ]

コメントはまだありません。