- PR -

CからC#を呼ぶ方法

投稿者投稿内容
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-12-01 09:02
2.COMのディスパッチインターフェイスを使った呼び出し方 です。

コード:
// ディスパッチインターフェイスを使った呼び出しサンプル

#include <objbase.h>

void main()
{
	HRESULT hr;

	// COMライブラリの初期化
	CoInitialize(NULL);

	// ProgIDからCLSIDを取得
	CLSID clsid;
	hr = CLSIDFromProgID(L"ManagedLibrary.Class1", &clsid);

	if (SUCCEEDED(hr))
	{
		// ManagedLibrary.Class1のインスタンス生成、IUnknownインターフェイスの取得
		IUnknown* pUnk = NULL;
		hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnk);
		if (SUCCEEDED(hr))
		{
			// IDispatchインターフェイスの取得
			IDispatch* pDisp = NULL;
			hr = pUnk->QueryInterface(IID_IDispatch, (void**)&pDisp);
			if (SUCCEEDED(hr))
			{
				// Method1のDISPIDを取得
				DISPID dispid = 0;
				OLECHAR* pszName[] = {L"Method1"};
				hr = pDisp->GetIDsOfNames(IID_NULL, pszName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
				if (SUCCEEDED(hr))
				{
					// Method1のパラメータ設定
					DISPPARAMS params;
					params.rgvarg = NULL;
					params.rgdispidNamedArgs = NULL;
					params.cArgs = 0;
					params.cNamedArgs = 0;

					// Method1を呼び出す
					pDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);
				}
				// IDipatchインターフェイスのリリース
				pDisp->Release();
			}
			
			// IUnknownインターフェイスのリリース
			pUnk->Release();
		}
	}

	// COMライブラリのクローズ
	CoUninitialize();
}


Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-12-01 09:03
3.COMのカスタムインターフェイスを使った呼び出し方 です。

コード:
// カスタムインターフェイスを使った呼び出しサンプル

#include <objbase.h>


// カスタムインターフェイスの定義

struct __declspec(uuid("7c2d873f-c96e-3bbd-bd72-a966a62ea48b"))
Class1;

struct __declspec(uuid("80d757c4-2619-3a12-a5f6-a3f2ceacd1db"))
_Class1 : IDispatch
{
      virtual HRESULT __stdcall ToString (/*[out,retval]*/ BSTR * pRetVal) = 0;
      virtual HRESULT __stdcall Equals (/*[in]*/ VARIANT obj, /*[out,retval]*/ VARIANT_BOOL * pRetVal) = 0;
      virtual HRESULT __stdcall GetHashCode (/*[out,retval]*/ long * pRetVal) = 0;
      virtual HRESULT __stdcall GetType (/*[out,retval]*/ void * * pRetVal) = 0;

      virtual HRESULT __stdcall Method1 () = 0;
};


void main()
{
	HRESULT hr;

	// COMライブラリの初期化
	CoInitialize(NULL);

	// ManagedLibrary.Class1のインスタンス生成
	_Class1* pClass1 = NULL;
	hr = CoCreateInstance(__uuidof(Class1), NULL, CLSCTX_INPROC_SERVER, __uuidof(_Class1), (void**)&pClass1);

	if (SUCCEEDED(hr))
	{
		// Method1を呼び出す
		pClass1->Method1();

		// Class1のインスタンスをリリース
		pClass1->Release();
	}

	// COMライブラリのクローズ
	CoUninitialize();
}


Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-12-01 09:04
4.CorBindToRuntimeEx関数を使用してCRLホストを作成した呼び出し方 です。

コード:
// CLRホストを作成して呼び出すサンプル

#include <Mscoree.h>
#pragma comment(lib, "Mscoree.lib")

#import "C:\\\\WINDOWS\\\\Microsoft.NET\\\\Framework\\\\v1.1.4322\\\\Mscorlib.tlb" raw_interfaces_only
using namespace mscorlib;

void main()
{
	HRESULT hr;

	// CLRにバインドする
	ICorRuntimeHost* pHost = NULL;
	hr = CorBindToRuntimeEx(L"v1.1.4322", L"wks", 0, CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (void**)&pHost);

	if (SUCCEEDED(hr))
	{
		// ホストを開始する
		pHost->Start();

		// アプリケーションドメイン(IUnknown)の取得
		IUnknown* pUnkAppDomain;
		hr = pHost->GetDefaultDomain(&pUnkAppDomain);

		if (SUCCEEDED(hr))
		{
			// アプリケーションドメイン(_AppDomain)の取得
			_AppDomain* pAppDomain = NULL;
			hr = pUnkAppDomain->QueryInterface(__uuidof(_AppDomain), (void**)&pAppDomain);

			if (SUCCEEDED(hr))
			{
				// ManagedLibrary.dllからManagedLibrary.Class1のインスタンス生成
				_ObjectHandle* pObjHandle = NULL;
				hr = pAppDomain->CreateInstanceFrom(_bstr_t("c:\\\\ManagedLibrary.dll"), _bstr_t("ManagedLibrary.Class1"), &pObjHandle);
				if (SUCCEEDED(hr))
				{

					VARIANT vtUnwrapped;
					pObjHandle->Unwrap(&vtUnwrapped);

					if (SUCCEEDED(hr) && vtUnwrapped.vt == VT_DISPATCH)
					{
						IDispatch* pDisp = vtUnwrapped.pdispVal;

						// Method1のDISPIDを取得
						DISPID dispid = 0;
						OLECHAR* pszName[] = {L"Method1"};
						hr = pDisp->GetIDsOfNames(IID_NULL, pszName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
						if (SUCCEEDED(hr))
						{
							// Method1のパラメータ設定
							DISPPARAMS params;
							params.rgvarg = NULL;
							params.rgdispidNamedArgs = NULL;
							params.cArgs = 0;
							params.cNamedArgs = 0;

							// Method1を呼び出す
							pDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);
						}


						pDisp->Release();
					}

					pObjHandle->Release();
				}

				pAppDomain->Release();
			}

			pUnkAppDomain->Release();
		}

		// ホスト停止する
		pHost->Stop();

		pHost->Release();
	}
}


Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-12-01 09:07
以上で、終わりです。

汚いソースコードでスイマセンでした。
コード等に間違いがあれば、ご指摘お願いいたします。

Hobbit
会議室デビュー日: 2004/01/28
投稿数: 6
投稿日時: 2005-12-01 10:58
返信遅くなりました。
siaさん、渋木宏明(ひどり)さん、Tdnr_Symさん、回答ありがとうございます。

参考にし、やってみたいと思います。

やりたいこと:C#で作成したDLL(COM)を .c(拡張子)から呼びたいのです。
       .c側は、VC.NETをコンパイラとしています。

初心者の上、その他情報をお持ちの方は、お教え願います。

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