アンマネージドからマネージドコードを呼び出す

画像 マネージコードからアンマネージコードを呼び出すタスクに非常に頻繁に直面します。このタスクには、単一の属性[DllImport]MSDNで詳しく説明されている追加のルールの形式のシンプルなソリューションがあります。 逆問題はあまり一般的ではありません。 この記事では、これを行う方法の小さな例を検討します。 網羅的であると見なされるべきではなく、一連の思考と概念としてのみ見なされるべきです。 それでは始めましょう。





この例は、3つのプロジェクトで構成されます。

  1. MixedLibrary-C ++ / CLI
  2. SimpleLibrary-C#
  3. Win32App-C ++


画像



最も単純なSimpleLibraryから始めましょう。 このライブラリには、2つの数値を追加して結果をコンソールに出力する1つの単純なサービスが含まれています。



public class Service { public void Add(Int32 a, Int32 b) { Console.WriteLine("Hello from Managed Code!"); Console.WriteLine(String.Format("Result: {0}", a + b)); } }
      
      







それでは、 MixedLibraryライブラリーに移りましょう。 このライブラリには、SimpleServiceのラッパークラスが含まれています。 CppService.hファイルの内容:



 //   ,     //      #ifdef INSIDE_MANAGED_CODE # define DECLSPECIFIER __declspec(dllexport) # define EXPIMP_TEMPLATE #else # define DECLSPECIFIER __declspec(dllimport) # define EXPIMP_TEMPLATE extern #endif namespace MixedLibrary { class DECLSPECIFIER CppService { public: CppService(); virtual ~CppService(); public: void Add(int a, int b); private: void * m_impl; }; }
      
      





CppService.cppファイルの内容:



 #include "CppService.h" using namespace System; using namespace System::Runtime::InteropServices; using namespace SimpleLibrary; namespace MixedLibrary { CppService::CppService() { Service^ service = gcnew Service(); m_impl = GCHandle::ToIntPtr(GCHandle::Alloc(service)).ToPointer(); } CppService::~CppService() { GCHandle handle = GCHandle::FromIntPtr(IntPtr(m_impl)); handle.Free(); } void CppService::Add(int a, int b) { GCHandle handle = GCHandle::FromIntPtr(IntPtr(m_impl)); Service^ service = safe_cast<Service^>(handle.Target); service->Add(a, b); } }
      
      







また、コンパイルのために、プリプロセッサディレクティブINSIDE_MANAGED_CODEを追加する必要があります。



画像



最後の仕上げは、通常のアンマネージアプリケーションです。



 #include "stdafx.h" #pragma comment(lib, "../Debug/MixedLibrary.lib") #include <iostream> #include "../MixedLibrary/CppService.h" using namespace std; using namespace MixedLibrary; int main() { CppService* service = new CppService(); service->Add(5, 6); cout << "press any key..." << endl; getchar(); }
      
      





そして、もちろん、結果:



画像



投稿者: nikitam



All Articles