Twitter / Marupeke_IKD: Windows7下でVisualStudio2005 …
https://twitter.com/Marupeke_IKD/status/245237326995927040
なところで、「Windows7下でVisualStudio2005で64bitなATLをVC++で作って、それを同じくVS2005環境で64bitビルドなVBで使おうとして「参照の追加」をするのだけど」の部分が気になって、一応確認してみたという話を少し。
VB6 自体は、Windows 7 上では動かないので、
- Windows 7 上の Visual Studio 2005 で 64bit の COM を作成
- Windows XP(かな?)の VB6 で先の COM を参照
なところでしょう。「VB の参照設定に出てこない」というところは、ファイルを参照させれば良いような気もするのですが、ちょっと実験してみます。
■環境
同じ環境を用意したい…つーのは面倒なので、似た環境を用意します。
- Windows 7 x64 の Visual Studio 2010 で COM を作る。
- Windows 7 x64 の Excel x86 を使って試す。
VB6 から参照するのも、Excel VBA から参照するのも似たようなものなので、これでテストします。以前、よくやっていた方法です。
■ATLでCOMを作る
- Visual Studio 2010 で「ATLプロジェクト」を選択
- プロジェクトに「ATLシンプル オブジェクト」を追加
- インターフェースを「デュアル」にするのを忘れずに
- クラスビューを使って、適当にメソッドやプロパティを追加(ここでは ICSmpのほうに追加)
IDL ファイルが自動生成されます。
[ object, uuid(A64C2AE7-E5C9-4B95-9C69-B48CB5E97966), dual, nonextensible, pointer_default(unique) ] interface ICSmp : IDispatch{ [propget, id(1)] HRESULT Length([out, retval] SHORT* pVal); [propput, id(1)] HRESULT Length([in] SHORT newVal); }; [ uuid(9394A921-EE32-4302-B544-90EC6D538D69), version(1.0), ] library SampleAtlCom64Lib { importlib("stdole2.tlb"); [ uuid(C8A6D4E6-BFAF-48B4-AE57-F65847F2ACA6) ] coclass CSmp { [default] interface ICSmp; }; };
- プロパティのコードを修正
// CCSmp STDMETHODIMP CCSmp::get_Length(SHORT* pVal) { *pVal = m_length; return S_OK; } STDMETHODIMP CCSmp::put_Length(SHORT newVal) { m_length = newVal; return S_OK; }
ひとまず、これをビルドすると「Win32」のほうの 32bit 版の COM が作成できます。
■64bit版のCOMを作る
構成マネージャを使って「新規作成」をします。すると、Win32 の構成をコピーして「x64」の構成ができます。
VC++のライブラリは自動的にx64のほうに切り替えられます(これは、VS2005の頃は手動だったはず)。
これをビルドすると、x64/Debug というフォルダに COM が作成されます。Win32 のほうは、Debug フォルダですね。
■Excel VBA から 64bit COM を参照する
Excel VBA を立ち上げて、「ツール」→「参照設定」を開きます。
参照ボタンを押して、先の x64/Debug にある COM(*.dll)を参照させます。
無事に参照が出来た模様
オブジェクトブラウザでも確認
さっき適当に作った Length というプロパティが見れます。
■Excel VBA で動作確認する。
テストコードを使ってステップ実行してみる。
まぁ、普通に実行ができるわけです。
一応 Excel 2010 を確認しておくと、「ファイル」→「ヘルプ」から 32ビット版なのか 64ビット版なのかが分かります。
■どうして、Marupeke_IKD さんの環境では動かないのか?
という訳で、手元の環境では ATL で x64 の COM を作って 32ビット版の Excel VBA から利用できたわけです。
ただし、VB6 の 64ビット環境については、
Visual Basic 6.0 で 64 ビットの Windows オペレーティング システムの使用方法について
http://support.microsoft.com/kb/894373/ja
に書いてある通り、微妙な動きをするそうなので Win32 に揃えてしまったほうがよさそうですね。
あと、Excel 2010 のヘルプを開いて「64」で検索して、「Microsoft Office の 32 ビット版と 64 ビット版を選択する」の項目を見ると、いまいち Office 64bit の下位互換性が不完全であることが分かります。まぁ、不完全というか「切り捨てた」と言っていいのでしょうが、インストールしている office が 32ビットなのか64ビットなのかを判別しながら、Excel VBA を組むのはやりたくないですよね。という訳で、特に不具合がなければ32ビット版にするのがよいのかも。
このテストで作ったのはシンプルな「ATLシンプル オブジェクト」なので、MFC やら外部 DLL を使っている場合は、もっと注意が必要ですよね。そのあたりでうまく参照設定できないのかもしれません。