C++/CLIとIntelliSense – C++/CLIの冷遇はまだ続く

Visual Studio 2010ではC++/CLIのIntelliSenseが機能しないという制限があります。これはベータ2の段階から変わらず、フィードバックセンターにも以下のように登録されています。

■C++/CLIでもIntelliSenseが機能してほしい
https://connect.microsoft.com/VisualStudioJapan/feedback/details/519716/c-cli-intellisense

この状況はVisual Studio 2010 SP1 Betaでも改善されておらず、USのConnectを覗いてみました。

■Intellisense not working with VS2010 C++/CLI projects
https://connect.microsoft.com/VisualStudio/feedback/details/626825/intellisense-not-working-with-vs2010-c-cli-projects

ということで、SP1でもC++/CLIの冷遇は変わらないようです。
「将来のバージョンで」ってばっかりで、改善されないのはいかがなものか…。
これでは、私のようなC++/CLI層を書くことがある人からすると、Visual Studio 2010に移行するのは逆に苦労が待っているようにしか思えない…。

2011/03/05 C++/CLIのIntelliSenseの今後 : http://azulea.wordpress.com/2011/03/05/ccli%e3%81%aeintellisense/

ソーシャルプラットフォームでの新規投稿時の類似スレッド検索

MSDN フォーラム、TechNet フォーラム、Answers フォーラムで採用されているフォーラム機能では、新規のスレッドを作成する際に入力したタイトルからの類似スレッドが検索され、提案される。
この提案されたスレッドで問題が解決すれば、新しいスレッドは不要となるわけだが、どの程度、機能しているかはよく分かりません。

質問者側からの意見も聞いてみたいかなぁ…。

Visual C++ 2008での参照設定の画面

Visual C#やVisual Basicと毛並みが異なるので、参考までにスクリーンショットを載せておきます。
この画面はプロジェクトのプロパティで表示でき、左側のノードで共通プロパティ→Framework と参照と辿ります。

GraphicsDevice.DrawUserPrimitivesのメタデータの表示方法

メタデータを見る方法ですが、下記の赤枠で囲っている部分にカーソルを合わせてF12キーを押します。
環境のよってはキーが異なるので、駄目なときは右クリックメニューから「定義へ移動」をクリックします。

すると、次のような画面が開きます。
(注意:ReSharperを導入しているとオブジェクトブラウザが表示されるため、下記のような画面にはなりません)

もしくは、オブジェクトブラウザからMicrosoft.Xna.Framework.Graphics.GraphicsDeviceと辿って、右側からDrawUserPrimitves<T>を選択すると、下側に情報が表示されます。

デザイナでコントロールの名前とクラスの確認方法

デザイナでコントロールを選択すると、そのコントロールのプロパティが表示されます。
IDEで見つからないときは、”表示”メニューから”プロパティ ウィンドウ”を選択して下さい。

※画像はクリックすると拡大します。

コンボボックスの部分にコントロールの名前と、どのクラスなのかが表示されています。

VC2005 Express 製品登録のフロー

2015/07/09追記:2005 バージョンの Express の登録キー発行などは終了した可能性があります。

こちらの記事を参照してください。

——

MSDNフォーラムでの回答用です。
http://social.msdn.microsoft.com/Forums/ja-JP/vcgeneralja/thread/1dde89b7-078f-40f3-986f-6be846b0e5e8

Visual C++ 2005 Express Editionを起動し、ヘルプメニューから製品の登録を選択します。

表示されたダイアログから今すぐ登録をクリックします。

ブラウザが起動しますので、必要に応じてLive IDの登録、認証、ログイン等を行って下さい。
最終的には下記のような画面が表示されます。

赤い枠で囲まれている部分に登録用のキーが記述されています。

MouseClickイベントを設定する

Visual Studio 2005/2008ではプロパティウィンドウからイベントを追加できます。
設定したいコントロールを選択した状態で、プロパティウィンドウの稲妻マークをクリックして表示を切り替えます。

MouseClickイベントであれば、スクロールすると出てくるのでその行をダブルクリックするとコードエディタにイベントのひな形が追加されます。

C#でCOMを作る(とりあえず動くところまで)

★ご注意


CLR 2.0、CLR 1.xが同じプロセス空間にロードできない問題と互換性の問題があるため、マネージコードでCOMを作ることはお薦めしません。

 

0.はじめに

@ITでサンプルよこせーというようなニュアンスの発言を受け取ったのでのんびりと書いていきましょう。
環境はVisual Studio 2008 Professionalです。

 

1.プロジェクトを作る

「クラスライブラリ」を選択して、プロジェクトを作ります。
.NET Frameworkのバージョンの選択はお好みでどうぞ。

 

2.インターフェースを作る

プロジェクトメニュー等から新しい項目を追加でインターフェースを追加します。

 

3.インターフェースにCOMとして公開するために必要な属性をつける

ComVisible属性でCOMに公開するかどうかを設定でき、trueだと公開になります。
ClassInterface属性で遅延バインディングを認めるという意味でAutoDispatchにしています。必要に応じて変えて下さい。
最後のGuid属性でインターフェースに対してGUIDを設定しますが、このGUIDはツールでインターフェースやクラス毎に必ず違うものを生成して下さい。
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.InterfaceType(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsDual)]
[System.Runtime.InteropServices.Guid("")]
public interface ITestClass
{
}
Visual Studio 2005/2008 Professionalであれば、ツールメニューに「GUIDの作成」があるので、
このツールで「4.Registry Format」で「Copy」ボタンを押して、クリップボードにコピーした文字列をGuid属性のところに入れます。
この際に、{ }の部分は外して下さい。
連続して生成する場合は、「New GUID」ボタンを押して下さい。
例:{D62189BE-C74D-46f5-8223-E0B8EC508BE5}が出てきたら、Guid属性には”D62189BE-C74D-46f5-8223-E0B8EC508BE5”を設定する。
 

 

4.インターフェースにメソッド・プロパティを追加

ひとまず、こんなところで、作ってみました。

[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.InterfaceType(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsDual)]
[System.Runtime.InteropServices.Guid("")]
interface ITestClass
{
    void HelloWorld();
    int Plus(int left, int right);
    int Number
    {
        get;
        set;
    }
}

 

5.インターフェースを実装するクラスを追加

毎度おなじみのプロジェクトの新しい項目の追加からクラスを作成します。

 

作成されたクラスで、インターフェースを実装するというように書きます。

public class Test : ITestClass
{
}
さらにクラス側にも色々と属性をつけておきます。
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDispatch)]
[System.Runtime.InteropServices.Guid("")]
public class Test : ITestClass

 

ここでITestClassと書いた部分にカーソルを合わせると下線が出てくるのでクリックして、メニューからインターフェースを実装しますを選択する。

そうすると、インターフェースを実装するスケルトンコードがずらずらと出てくるので中身を埋めていきます。
(プロパティのコードは何となく書いていますが、C#3.0あたりからはget;set;といった感じに省略できるはず)

public void HelloWorld()
{
    Console.WriteLine("Hello! World!");
}

public int Plus(int left, int right)
{
    return left + right;
}

private int number;

public int Number
{
    get { return this.number; }
    set { this.number = value; }
}

 

6.レジストリ登録するためにプロジェクトの設定を変えておく

順番が前後しましたが、プロジェクトの設定を変えておかないと、COMとして利用できる形に登録されません。
プロジェクトメニューから ~ のプロパティを選択します。
もしくはソリューションエクスプローラでプロジェクトを右クリックしてプロパティを選択しても構いません。

表示された画面から「ビルド」タブを選択して、下の方にある「COM相互運用機能の登録」にチェックを入れておきます。

この設定をしておくことで、ビルドしたときに自動的にレジストリに登録されるようになります。
(管理者権限が必要ですので、Vistaの場合はVisual Studioを管理者権限で起動する必要があるかもしれません。)

7.ビルドする

構文エラーとか特に問題がなければ、さっくりとビルドが成功するはずです。

 

8.使ってみる

Rubyは普段触りません。なので、検索で引っかかった情報を元に適当に組みました。

require 'win32ole'
instance = WIN32OLE.new('ComTestLibrary.Test')

instance.HelloWorld()

i = instance.Plus(1, 2)
print(i, "\n")

instance.Number = i
i = 25
print(instance.Number, "\n")
i += instance.Number
print(i, "\n")
instance.Number = 9
print(instance.Number, "\n")

このファイルをruby test.rbにような形で食わせると、次のように出力されます。

Hello! World!
3
3
28
9

ちゃんとCOMが呼び出せている様子です。
とりあえず、導入部分としては目的を達成できたかと思います。

 

9.留意点

・今回WIN32OLEモジュールを使っています。Dispatchなインターフェースがないとこの方法では使えないので属性の設定を無闇に変更しないようにしましょう。
・「とりあえず動いた」の状態ですので、これをスケルトンコードにしないようにしましょう。
・ビルドした環境以外で今回のDLLをレジストリに登録するには regasm コマンドを使用します。
・属性の意味はMSDNを見て調べましょう。

 

10.サンプルソース

http://cid-9e1932af4be9e15d.skydrive.live.com/embedrowdetail.aspx/.Public/ComTestLibrary.zip

※GUIDはそのまま使用しないようにしましょう。

カテゴリー: C#