[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]
「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>.NET開発]]

* 目次 [#l92341c6]
#contents

*概要 [#i8022e3e]
まずは「[[マーシャリング]]」を参照して下さい。~
基本が解ればなんとかなると思います。

*方法 [#wf43896d]
**アンマネージドコードのインターフェイスをマネージドコード(.NET)に公開する方法 [#y87eef73]
以下の2つの方法があります。

-DLLのインターフェイスをマネージドコード(.NET)に公開する方法。
--@IT:.NET TIPS Win32 APIやDLL関数を呼び出すには? - C#~
http://www.atmarkit.co.jp/fdotnet/dotnettips/024w32api/w32api.html

-COMのインターフェイスをマネージドコード(.NET)に公開する方法。
--.NET からの COM コンポーネントの呼び出し~
http://msdn.microsoft.com/ja-jp/library/dd297671.aspx

**マネージドコード(.NET)のインターフェイスをアンマネージドコードに公開する方法 [#t34c2941]
以下の2つの方法があります。

-.NETのアンマネージド拡張(C++/CLI)でDLLインターフェイスを[[DLLユーザ>DLL/COMユーザ]]に公開する方法と
-.NETアセンブリでCOMインターフェイスを[[COMユーザ>DLL/COMユーザ]]に公開する方法があります。

**サンプルコード [#e290321a]
コチラが参考になります。

[[OpenTouryoProject>https://github.com/OpenTouryoProject]]-[[SampleProgram>https://github.com/OpenTouryoProject/SampleProgram]]

***.NET(manage)⇔VC、VB6(unmanage)の相互運用 [#kf1bf207]
Other-InteropWithUnmanage at master~
https://github.com/OpenTouryoProject/SampleProgram/tree/master/Other/InteropWithUnmanage~
>.NET(manage)⇔VC、VB6(unmanage)の相互運用のテストです。

***アンマネージコードからマネージコードを呼び出す [#s407336b]
[[上記>#kf1bf207]]の逆を行なう相互運用。

Other-DotNETBridge at master~
https://github.com/OpenTouryoProject/SampleProgram/tree/master/Other/DotNETBridge~
>Win32 DLL と C++/CLIのブリッジDLLを使用して、アンマネージコードからマネージコードを呼び出す。

*事例 [#e13c7358]

**C/C++側のコールバック関数を.NETから呼び出したい [#vae2a281]
マーシャリングの動作のイメージができていないと、正しい処理を実装できない可能性があります。~
e.g.: 以前、callback実装を正しく実装できないことがあった。

***質問 [#u83bfdb8]
-C++のEXEからC#のメソッドを呼び出します。
-このときの引数でC++側のコールバック関数のアドレスを渡します。
-このあと、外的要因でC#のDLLから上記のコールバックを呼び出そうとしていますが、~
コールバック呼び出しで例外エラーとなります。

***回答 [#f52beaa8]
-C++からC#は直接呼べないのでアンマネージド拡張(C++/CLI)でDLLのエクスポート関数経由で.NETに接続する必要があると思います。
-また、.NETにCの関数ポインタを直接渡しても.NETからの呼び出しはできないので、C++/CLI経由にする必要があると思います。

そこで思いついたのは、

+C++/CLI内部でコールバックするメソッドを持ったオブジェクトを作成し、~
C#のメソッド経由でそのオブジェクトを渡す。~
C#からこのオブジェクトのメソッドを経由してC++にコールバックする。
+C++/CLIでC#から呼ぶためのDLLエクスポート関数を作る。~
このエクスポート関数にCの関数ポインタを渡してコールバックする。

という2つの方法です。

逆(.NETのコールバック関数をC/C++から呼び出したい)は~
標準の相互運用マーシャラーでサポートされるようです。

-[C#] 引数にcallbackを持つDLLメソッドの使用について - Insider.NET - @IT~
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=12478&forum=7~

>恐らく、自動的にマーシャリングされるのだと思います。
--行きはマーシャリング(デリゲードからポインタ)
--帰りもマーシャリング(多分Cにラッパのポインタが渡る)

***結果 [#abacdc98]
[[上記>#f52beaa8]]の1.で解決しました。

*参考 [#x720ec35]

-CLR Inside Out Marshaling between Managed and Unmanaged Code~
http://msdn.microsoft.com/ja-jp/magazine/cc164193.aspx
--[InAttribute] と [OutAttribute]
--キーワード out および ref と、参照による受け渡し
--戻り値
--StringBuilder と[[マーシャリング]]
--コピーと固定
--メモリの所有権
--逆 P/Invoke とデリゲートの有効期間
--P/Invoke Interop Assistant

**MSDN [#mf36211a]
-アンマネージ コードとの相互運用~
http://msdn.microsoft.com/ja-jp/library/sd10k43k.aspx
--アンマネージ コードとの相互運用性に関する方法  
--.NET Framework への COM コンポーネントの公開 
--COM への .NET Framework コンポーネントの公開 
--アンマネージ DLL 関数の処理 
--相互運用のためのデザインの考慮事項 
--相互運用マーシャリング 
--方法: HRESULT に例外を割り当てる  
--ジェネリック型を使用する相互運用

**その他 [#acfd7f90]

-pinvoke.net the interop wiki!~
http://www.pinvoke.net/

-@IT - C# VB.NET VS.NET
--.NET TIPS Win32 APIやDLL関数を呼び出すには?~
http://www.atmarkit.co.jp/fdotnet/dotnettips/024w32api/w32api.html
--.NET TIPS Win32 APIやDLL関数に文字列や文字列バッファを渡すには?~
http://www.atmarkit.co.jp/fdotnet/dotnettips/025w32string/w32string.html
--.NET TIPS Win32 APIやDLL関数に構造体を渡すには?~
http://www.atmarkit.co.jp/fdotnet/dotnettips/026w32struct/w32struct.html
--.NET TIPS Win32 API呼び出しを手軽に記述するには?~
http://www.atmarkit.co.jp/fdotnet/dotnettips/166pinvoke/pinvoke.html

**ツール類 [#p37ed057]

-.NET用のAPIビューア .NET Tips C#, VB.NET~
http://dobon.net/vb/dotnet/links/apiviewer.html

--Win32APIViewer .NET~
リンク切れ?

--PINVOKE.NET Add-In for Visual Studio 2003 and 2005~
http://www.red-gate.com/products/dotnet-development/pinvoke/

----
Tags: [[:.NET開発]]
Tags: [[:Windows]], [[:プログラミング]], [[:.NET開発]]


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS