- PR -

CからC#を呼ぶ方法

投稿者投稿内容
Hobbit
会議室デビュー日: 2004/01/28
投稿数: 6
投稿日時: 2005-11-30 21:09
C#で作成したDLL/tlbをC から呼びたいのですが、
C では、どのように呼ぶのでしょうか。

ご存知の方、お教え願います。
sia
常連さん
会議室デビュー日: 2004/05/02
投稿数: 38
投稿日時: 2005-11-30 21:43
こんばんわ。

tlbと仰っていると言うことはCOM前提の話ということでしょうか?
#知っている限りではCCW(Com Collable Wrapper)以外からは呼び出せないはずですが。

COM経由で呼び出したことはないので、知識のみの話になってしまいますが、
1.tlbexpで作成したアセンブリのタイプライブラリ生成。
2.タイプライブラリをクライアントマシンで登録。
3.通常のCOM経由で呼びだす。
(おそらくスレッドアパートメントモデルに起因する厄介ごとなどが待ち受けていますが・・・。)

と、推測で書いてみましたが、どこまでできてどこからができないのかを明示された方がレスがつきやすいように思います。
Hobbit
会議室デビュー日: 2004/01/28
投稿数: 6
投稿日時: 2005-11-30 21:51
回答ありがとうございます。
COM前提です。
tlbexpで、タイプライブラリまで作成しました。
Cからどう呼ぼうか悩んでいるところです。

渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2005-11-30 22:32
引用:

tlbexpで、タイプライブラリまで作成しました。
Cからどう呼ぼうか悩んでいるところです。



最近の VC++ なら、#imports でどうぞ。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-11-30 22:57
こんにちは。

C言語なのですか?C++(VC++)ではなくですか?
なんだか険しい道のりのような気がしますが…

とりあえず、VC++(.NET)からという解釈で回答させていただきます。
私の認識している、やり方は3通りあります。

1.managed C++を使う
  VC++.NET(managed C++)からだと
  #usingディレクティブを使って、
  素直にマネージコードを呼び出すことができます。

2.COMを経由する
  作成した.NETコンポーネントをCOMとしてエクスポート・登録します。
  C#クラスのインターフェイスを変更するたびに、タイプライブラリも
  生成・登録しなおす必要があるので保守が面倒です。
  VC++からだと#importディレクティブを使って
  COMを呼び出すことができます。

3.アンマネージAPIのCorBindToRuntimeExを使用する
  この方法も結局、COM経由ということになるかもしれませんが、
  ICorRuntimeHostインターフェイスやIDispatchインターフェイスなどがすでに、ヘッダファイルに
  定義してあるので、C言語からでも比較的使いやすいかもしれません。

どうでしょうか。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-12-01 02:00
こんばんは。

追記ですが、
managed C++を使わないのであれば、やはりCOMラッパーを使うことになりそうですが
アンマネージ コードとの相互運用

あとはCOMのどのインターフェイスをつかってアクセスするのかを決めなければならないですね。
InterfaceTypeAttribute属性
を使えば、デュアル・ディスパッチ専用・ IUnknown 専用を選択できるようですが、デフォルトでデュアルになるようです。

ディスパッチインターフェイスも、カスタムインターフェイスも一長一短なので、
よければ下記を参考にしてみてください。

・IDispatch/IDispatchExを使う場合
 このインターフェイスはスクリプト言語用なので、基本的にあまりC言語には向いていないかもしれません。
 メソッド呼び出しが煩わしいですが IDispatch/IDispatchExは既存のインターフェイスなので、
 あらたにカスタムインターフェイスを定義する必要がありません。

・カスタムインターフェイスを使う場合
 こちらは自分でC/C++用のカスタムインターフェイスを定義してやる必要があります。
 VC++の#importディレクティブは自動生成してくれますが、手作業で定義するのは結構手間かもしれません。
 しかし、メソッド呼び出しは楽になります。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-12-01 08:58
おはようございます。

昨晩の説明では、抽象的すぎて分かりづらかったかな?と思い直し
具体的なコードを書いて見ました。

4通りの呼び出し方のサンプルプログラムを示したいと思います。
#コードはこの投稿のあと、順次、投下していきたいと思います。

 1.managed C++を使った呼び出し方
 2.COMのディスパッチインターフェイスを使った呼び出し方
 3.COMのカスタムインターフェイスを使った呼び出し方
 4.CorBindToRuntimeEx関数を使用してCRLホストを作成した呼び出し方


呼び出される側の C# DLLは次のようなコードです。

コード:
// C/C++から呼び出されるC#クラスライブラリ(ManagedLibrary.dll)

using System;
using System.Runtime.InteropServices;

namespace ManagedLibrary
{
	// デュアルインターフェイスでCOMを公開する
	[ClassInterface(ClassInterfaceType.AutoDual)]
	public class Class1
	{
		// コンストラクタ
		public Class1()
		{
		}

		// テスト用メソッド
		public void Method1()
		{
			// コンソールに出力する
			System.Console.WriteLine("ManagedLibrary.Class1.Method1が呼び出されました。");
		}
	}
}



また作成したDLLには、以下のように登録しています。

1.厳密名の指定
  ・snコマンドからキーペアを作成します。
    sn -k c:\\ManageLibrary.snk
  ・AssemblyInfo.csを開き、[assembly: AssemblyKeyFile("c:\\\\ManageLibrary.snk")]と編集してビルドする。
2.GACへの登録
  ・gacutilコマンドでアセンブリをGACへ登録します。
    gacutil -T c:\\ManageLibrary.dll
3.COMコンポーネントとして登録
  ・regasmコマンドでCOMコンポーネントとして登録します。
    regasm c:\\ManageLibrary.dll /tlb


では、呼び出しサンプルコードを投下していきます。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2005-12-01 09:00
1.managed C++を使った呼び出し方 です。

コード:
// managed C++を使った呼び出しサンプル

// オプション/clr または「マネージ拡張:はい」にすること

#using <mscorlib.dll>
#using "../ManagedLibrary/bin/Debug/ManagedLibrary.dll"

void main()
{
	// ManagedLibrary.Class1のインスタンス生成
	ManagedLibrary::Class1* pC = new ManagedLibrary::Class1();

	// Method1を呼び出す
	pC->Method1();
}

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