{"id":273114,"date":"2016-01-28T14:19:03","date_gmt":"2016-01-28T11:19:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=273114"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=273114","title":{"rendered":"Unmanaged C++ library \u0432 .NET. \u041f\u043e\u043b\u043d\u0430\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f"},"content":{"rendered":"<p>       \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u043f\u043e\u043b\u043d\u0430\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f C++ \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0432 managed \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Platform Invoke. \u041f\u043e\u0434 \u043f\u043e\u043b\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0435\u0439 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0435\u0451 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432 (\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 managed \u043a\u043e\u0434\u0435 \u043a\u0430\u043a \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b). \u042d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u00ab\u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u00bb \u0432 unmanaged \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u0412\u043e\u043f\u0440\u043e\u0441 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0443\u0436\u0435 \u043d\u0435 \u0440\u0430\u0437 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u043b\u0441\u044f \u043d\u0430 \u0445\u0430\u0431\u0440\u0435, \u043d\u043e, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043e\u043d \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u043f\u0430\u0440\u044b-\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432 managed \u043a\u043e\u0434\u0435. \u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u043c\u0438 \u0436\u0435 \u0441\u0442\u043e\u044f\u043b\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u0437\u044f\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c \u0438\u0437 C++ \u0438 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 .NET. \u0412\u0430\u0440\u0438\u0430\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0437\u0430\u043d\u043e\u0432\u043e, \u043f\u043e \u0440\u044f\u0434\u0443 \u043f\u0440\u0438\u0447\u0438\u043d, \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b\u0441\u044f, \u0442\u0430\u043a \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043b\u0438 \u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>  \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0435 \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0435\u0445 \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 unmanaged \u043c\u043e\u0434\u0443\u043b\u044f \u0432 .NET. \u0415\u0441\u0442\u044c \u0435\u0449\u0435 \u043d\u044e\u0430\u043d\u0441\u044b \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u0441\u0442\u0440\u043e\u043a, \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0438 \u0442.\u043f\u2026 \u041f\u043e \u044d\u0442\u0438\u043c \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u043c \u0435\u0441\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0430\u0442\u0435\u0439 \u043d\u0430 \u0445\u0430\u0431\u0440\u0435, \u0442\u0430\u043a \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u044d\u0442\u0438 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b\u0438\u0441\u044c.<\/p>\n<p>  \u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e .NET \u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u043d\u0430 \u0431\u0430\u0437\u0435 Platform Invoke \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u0430, \u0435\u0451 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043d\u0430 Mono + gcc.<\/p>\n<p>  <a name=\"first\"><\/a><\/p>\n<h2>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f sealed \u043a\u043b\u0430\u0441\u0441\u0430<\/h2>\n<p>  \u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0441\u043e\u0437\u043d\u0430\u0442\u044c \u043f\u0440\u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Platform Invoke \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u0448\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041d\u0435\u043b\u044c\u0437\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u0432\u0437\u044f\u0442\u044c \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<p>  \u041d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 Unmanaged \u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e:  <\/p>\n<pre><code class=\"cpp\">SomeType ClassName_methodName(ClassName * instance, SomeOtherType someArgument) {     instance-&gt;methodName(someArgument); } <\/code><\/pre>\n<p>  \u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043a \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c extern \u00abC\u00bb, \u0447\u0442\u043e\u0431\u044b \u0438\u0445 \u0438\u043c\u0435\u043d\u0430 \u043d\u0435 \u0434\u0435\u043a\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438\u0441\u044c C++ \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u043c. \u042d\u0442\u043e \u043f\u043e\u043c\u0435\u0448\u0430\u043b\u043e \u0431\u044b \u043d\u0430\u043c \u043f\u0440\u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u044d\u0442\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 .NET.<\/p>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u0430 \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u043a\u043b\u0430\u0441\u0441, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432 .NET. \u041f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u043a\u043b\u0430\u0441\u0441 \u043d\u0435\u043b\u044c\u0437\u044f \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 .NET \u0442\u0430\u043a\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a sealed. \u041a\u0430\u043a \u043e\u0431\u043e\u0439\u0442\u0438 \u044d\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0438 \u0441 \u0447\u0435\u043c \u043e\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u2014 \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0438\u0436\u0435.<br \/>  \u0410 \u043f\u043e\u043a\u0430 \u0432\u043e\u0442 \u0432\u0430\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  Unmanaged class:  <\/p>\n<pre><code class=\"cpp\">class A {     int mField; public:     A( int someArgument);     int someMethod( int someArgument); }; <\/code><\/pre>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438:  <\/p>\n<pre><code class=\"cpp\">A * A_createInstance(int someArgument) {     return new A(someArgument); }  int A_someMethod(A *instance, int someArgument) {     return instance-&gt;someMethod( someArgument); }  void A_deleteInstance(A *instance) {     delete instance; } <\/code><\/pre>\n<p>  \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432 .Net:  <\/p>\n<pre><code class=\"cs\">public sealed class A {     private IntPtr mInstance;     private bool mDelete;      [ DllImport( &quot;shim.dll&quot;, CallingConvention = CallingConvention .Cdecl)]     private static extern IntPtr A_createInstance( int someArgument);      [ DllImport( &quot;shim.dll&quot;, CallingConvention = CallingConvention .Cdecl)]     private static extern int A_someMethod( IntPtr instance, int someArgument);      [ DllImport( &quot;shim.dll&quot;, CallingConvention = CallingConvention .Cdecl)]     private static extern void A_deleteInstance( IntPtr instance);      internal A( IntPtr instance)     {         Debug.Assert(instance != IntPtr.Zero);         mInstance = instance;         mDelete = false;     }      public A( int someArgument)     {         mInstance = A_createInstance(someArgument);         mDelete = true;     }      public int someMethod( int someArgument)     {         return A_someMethod(mInstance, someArgument);     }      internal IntPtr getUnmanaged()     {         return mInstance;     }      ~A()     {         if (mDelete)             A_deleteInstance(mInstance);     }  } <\/code><\/pre>\n<p>  Internal \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0438 \u043c\u0435\u0442\u043e\u0434 \u043d\u0443\u0436\u043d\u044b, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u043a\u043b\u0430\u0441\u0441\u0430 \u0438\u0437 unmanaged \u043a\u043e\u0434\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0445 \u043e\u0431\u0440\u0430\u0442\u043d\u043e. \u0418\u043c\u0435\u043d\u043d\u043e \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 unmanaged \u0441\u0440\u0435\u0434\u0443 \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u043a\u043b\u0430\u0441\u0441 A \u043e\u0442\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0432 .NET \u0438 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0440\u044f\u0434 \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 (\u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e someMethod \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u043c virtual), \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u0432\u044b\u0437\u043e\u0432 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0438\u0437 unmanaged \u0441\u0440\u0435\u0434\u044b.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/079\/f21\/473\/079f2147399f46d4b499f51fe9dd8765.png\"\/><br \/>  <a name=\"second\"><\/a><\/p>\n<h2>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430<\/h2>\n<p>  \u0414\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u0430\u044f \u0441\u0432\u044f\u0437\u044c. \u0422.\u0435. \u0434\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432 managed \u0441\u0440\u0435\u0434\u0435. \u042d\u0442\u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u0437 unmanaged \u043a\u043e\u0434\u0430. \u0422\u0443\u0442 \u043d\u0430\u043c \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0434\u0443\u0442 Callback Methods, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043a Platform Invoke.<\/p>\n<p>  \u041d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 unmanaged \u0441\u0440\u0435\u0434\u044b Callback \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e:  <\/p>\n<pre><code class=\"cpp\">typedef void (*PFN_MYCALLBACK )(); int _MyFunction(PFN_MYCALLBACK callback); <\/code><\/pre>\n<p>  \u0410 \u0432 .NET \u0435\u0433\u043e \u0440\u043e\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u0438\u0433\u0440\u0430\u0442\u044c \u0434\u0435\u043b\u0435\u0433\u0430\u0442:  <\/p>\n<pre><code class=\"cs\">[UnmanagedFunctionPointerAttribute( CallingConvention.Cdecl)] public delegate void MyCallback (); [ DllImport(&quot;MYDLL.DLL&quot;,CallingConvention.Cdecl)] public static extern void MyFunction( MyCallback callback); <\/code><\/pre>\n<p>  \u0418\u043c\u0435\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u0432\u044f\u0437\u0438 \u043c\u044b \u043b\u0435\u0433\u043a\u043e \u0441\u043c\u043e\u0436\u0435\u043c \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u0432\u044b\u0437\u043e\u0432 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432.<\/p>\n<p>  \u041d\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u0432 unmanaged \u0441\u0440\u0435\u0434\u0435 \u043d\u0430\u043c \u0435\u0433\u043e \u0442\u043e\u0436\u0435 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u043a \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0422\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432 unmanaged \u0441\u0440\u0435\u0434\u0435. \u0412 \u044d\u0442\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u044b, \u043a\u0441\u0442\u0430\u0442\u0438 \u0433\u043e\u0432\u043e\u0440\u044f, \u0437\u0430\u043b\u043e\u0436\u0438\u043c \u0432\u044b\u0437\u043e\u0432\u044b Callback \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<p>  \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0431\u0435\u0437 \u043b\u043e\u0433\u0438\u043a\u0438 \u0432 managed \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u0445, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0438\u0445 \u0432 \u0432\u0438\u0434\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043a\u043e\u0434:<\/p>\n<p>  Unmanaged interface:  <\/p>\n<pre><code class=\"cpp\">class IB { public:     virtual int method( int arg) = 0;     virtual ~IB() {}; }; <\/code><\/pre>\n<p>  Unmanaged \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f  <\/p>\n<pre><code class=\"cpp\">typedef int (*IB_method_ptr)(int arg); class UnmanagedB : public IB {         IB_method_ptr mIB_method_ptr; public:         void setMethodHandler( IB_method_ptr ptr);         virtual int method( int arg);         \/\/... \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\/\u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 };  void UnmanagedB ::setMethodHandler(IB_method_ptr ptr) {        mIB_method_ptr = ptr; }  int UnmanagedB ::method(int arg ) {         return mIB_method_ptr( arg); } <\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434\u044b UnmanagedB \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442 \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u043c\u0443 \u0432\u044b\u0434\u0430\u0435\u0442 managed \u043a\u043b\u0430\u0441\u0441. \u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0441 \u043f\u043e\u0434\u0436\u0438\u0434\u0430\u0435\u0442 \u0435\u0449\u0435 \u043e\u0434\u043d\u0430 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0441\u0442\u044c. \u0414\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0432 unmanaged \u043a\u043e\u0434\u0435 \u0443 \u043a\u043e\u0433\u043e-\u0442\u043e \u0435\u0441\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 UnmanagedB, \u043c\u044b \u043d\u0435 \u0438\u043c\u0435\u0435\u043c \u043f\u0440\u0430\u0432\u0430 \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 \u0432 managed \u043a\u043e\u0434\u0435, \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u043d\u0430 \u0432\u044b\u0437\u043e\u0432 \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u043e\u0432. \u0420\u0435\u0448\u0435\u043d\u0438\u044e \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438:  <\/p>\n<pre><code class=\"cpp\">UnmanagedB *UnmanagedB_createInstance() {         return new UnmanagedB(); }  void UnmanagedB_setMethodHandler(UnmanagedB *instance, IB_method_ptr ptr) {         instance-&gt;setMethodHandler( ptr); }  void UnmanagedB_deleteInstance(UnmanagedB *instance) {         delete instance; } <\/code><\/pre>\n<p>  \u0410 \u0432\u043e\u0442 \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0432 managed \u043a\u043e\u0434\u0435:  <\/p>\n<pre><code class=\"cs\">public abstract class AB {     private IntPtr mInstance;      [DllImport(&quot;shim&quot;, CallingConvention = CallingConvention.Cdecl)]     private static extern IntPtr UnmanagedB_createInstance();      [DllImport(&quot;shim&quot;, CallingConvention = CallingConvention.Cdecl)]     private static extern IntPtr UnmanagedB_setMethodHandler( IntPtr instance,     [MarshalAs(UnmanagedType.FunctionPtr)] MethodHandler ptr);      [DllImport(&quot;shim&quot;, CallingConvention = CallingConvention.Cdecl)]     private static extern void UnmanagedB_deleteInstance( IntPtr instance);      [UnmanagedFunctionPointerAttribute( CallingConvention.Cdecl)]     private delegate int MethodHandler( int arg);      private int impl_method( int arg)     {         return method(arg);     }      public abstract int method(int arg);      public AB()     {         mInstance = UnmanagedB_createInstance();         UnmanagedB_setMethodHandler(mInstance, impl_method);     }      ~AB()     {         UnmanagedB_deleteInstance(mInstance);     }      internal virtual IntPtr getUnmanaged()     {         return mInstance;     }  } <\/code><\/pre>\n<p>  \u041a\u0430\u0436\u0434\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u0430\u0440\u0430:  <\/p>\n<ol>\n<li>\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c<\/li>\n<li>\u00ab\u0412\u044b\u0437\u044b\u0432\u0430\u0442\u0435\u043b\u044c\u00bb \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 (\u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0441 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u043e\u0439 impl). \u041c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043e\u043d \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u0422\u0430\u043a \u0436\u0435 \u0432 \u043d\u0451\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043b\u043e\u0436\u0435\u043d\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 (\u043a\u0430\u043a \u0432\u044b \u0443\u0436\u0435 \u0434\u043e\u0433\u0430\u0434\u0430\u043b\u0438\u0441\u044c, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u0441\u0440\u0435\u0434\u044b \u0432 \u0441\u0440\u0435\u0434\u0443 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f, \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0442\u043e\u0436\u0435 \u043d\u0430\u0434\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c)<\/li>\n<\/ol>\n<p>  \u0412\u043e\u0442 \u0438 \u0432\u0441\u0451. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 AB \u0438 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434 method. \u0415\u0441\u043b\u0438 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0430 \u0432 unmanaged \u043a\u043e\u0434 \u043c\u044b \u043e\u0442\u0434\u0430\u0434\u0438\u043c \u0432\u043c\u0435\u0441\u0442\u043e \u043d\u0435\u0433\u043e mInstance, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0447\u0435\u0440\u0435\u0437 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e\/\u0434\u0435\u043b\u0435\u0433\u0430\u0442. \u0415\u0441\u043b\u0438 \u0436\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 IB \u0438\u0437 unmanaged \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u0435\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 AB \u0432 managed \u0441\u0440\u0435\u0434\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0430 AB \u00ab\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\u00bb:  <\/p>\n<pre><code class=\"cs\">internal sealed class BImpl : AB {     [DllImport(&quot;shim&quot;, CallingConvention = CallingConvention.Cdecl)]     private static extern int BImpl_method( IntPtr instance, int arg);      private IntPtr mInstance;     internal BImpl( IntPtr instance)     {         Debug.Assert(instance != IntPtr.Zero);         mInstance = instance;     }      public override int method(int arg)     {         return BImpl_method(mInstance, arg);     }      internal override IntPtr getUnmanaged()     {         return mInstance;     }  } <\/code><\/pre>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438:  <\/p>\n<pre><code class=\"cpp\">int BImpl_method(IB *instance , int arg ) {         instance-&gt;method( arg); } <\/code><\/pre>\n<p>  \u041f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0451\u0442\u0443 \u044d\u0442\u043e \u0442\u0430 \u0436\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0431\u0435\u0437 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f <a href=\"#first\">\u0432\u044b\u0448\u0435<\/a>. \u041d\u0435 \u0441\u043b\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 BImpl, \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 UnmanagedB \u0438 \u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u043e\u0432. \u041f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c, \u043d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u0438, \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0438\u0445 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/520\/6a8\/d8d\/5206a8d8ddbb424fb520db8fd40cba21.png\"\/>  <\/p>\n<h2>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f<\/h2>\n<p>  \u0417\u0430\u0434\u0430\u0447\u0430 \u2014 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432. \u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043a\u043b\u0430\u0441\u0441 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u0432 unmanaged, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u0430\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b.<\/p>\n<p>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043b\u0430\u0441\u0441 C, \u0438\u043c\u0435\u044e\u0449\u0438\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432 unmanaged \u043a\u043e\u0434\u0435:  <\/p>\n<pre><code class=\"cpp\">class C { public:     virtual int method(int arg);     virtual ~C() {}; }; <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0432\u0438\u0434, \u0447\u0442\u043e \u044d\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. \u0418\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0442\u0430\u043a\u0436\u0435, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e <a href=\"#second\">\u0432\u044b\u0448\u0435<\/a>:<\/p>\n<p>  Unmanaged \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a \u0434\u043b\u044f \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u043e\u0432:  <\/p>\n<pre><code class=\"cpp\">typedef int (*\u0421_method_ptr )(int arg); class UnmanagedC : public cpp::C {     \u0421_method_ptr m\u0421_method_ptr; public:     void setMethodHandler( \u0421_method_ptr ptr);     virtual int method( int arg); };  void UnmanagedC ::setMethodHandler(\u0421_method_ptr ptr) {     m\u0421_method_ptr = ptr; }  int UnmanagedC ::method(int arg ) {     return m\u0421_method_ptr( arg); } <\/code><\/pre>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438:  <\/p>\n<pre><code class=\"cpp\">\/\/... \u043e\u043f\u0443\u0441\u0442\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u044b createInstance \u0438 deleteInstance  void UnmanagedC_setMethodHandler(UnmanagedC *instance , \u0421_method_ptr ptr ) {         instance-&gt;setMethodHandler( ptr); } <\/code><\/pre>\n<p>  \u0418 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432 .Net:  <\/p>\n<pre><code class=\"cs\">public class C {     private IntPtr mHandlerInstance;      [DllImport(&quot;shim&quot;, CallingConvention = CallingConvention.Cdecl)]     private static extern IntPtr UnmanagedC_setMethodHandler( IntPtr instance,     [MarshalAs(UnmanagedType.FunctionPtr)] MethodHandler ptr);      [UnmanagedFunctionPointerAttribute( CallingConvention.Cdecl)]     private delegate int MethodHandler( int arg);      \/\/... \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f\/\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430      private int impl_method( int arg)     {         return method(arg);     }      public virtual int method(int arg)     {         throw new NotImplementedException();     }      public C()     {         mHandlerInstance = UnmanagedC_createInstance();         UnmanagedC_setMethodHandler(mHandlerInstance, impl_method);     }      ~C()     {         UnmanagedC_deleteInstance(mHandlerInstance);     }      internal IntPtr getUnmanaged()     {         return mHandlerInstance;     }  } <\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043c\u0435\u0442\u043e\u0434 C.method \u0438 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u043d \u0438\u0437 unmanaged \u0441\u0440\u0435\u0434\u044b. \u041d\u043e \u043c\u044b \u043d\u0435 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u043b\u0438 \u0432\u044b\u0437\u043e\u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e. \u0417\u0434\u0435\u0441\u044c \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043a\u043e\u0434 \u0438\u0437 <a href=\"http:\/\/first\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u0441\u0442\u0430\u0442\u044c\u0438:<br \/>  \u0414\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0435\u0451 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0422\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u0435\u0451 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u0443\u0434\u0430\u043b\u044f\u0442\u044c. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0439 \u043a\u043e\u0434:  <\/p>\n<pre><code class=\"cpp\">\/\/... \u043e\u043f\u044f\u0442\u044c \u0436\u0435 \u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c createInstance \u0438 deleteInstance  int C_method(C *instance, int arg) {         return instance-&gt;method( arg); } <\/code><\/pre>\n<p>  \u0414\u043e\u043f\u0438\u043b\u0438\u043c .Net \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e:  <\/p>\n<pre><code class=\"cs\">public class C {     \/\/...      [DllImport(&quot;shim&quot;, CallingConvention = CallingConvention.Cdecl)]     private static extern int C_method(IntPtr instance, int arg);      public virtual int method(int arg)     {         return C_method(mInstance, arg);     }      public C()     {         mHandlerInstance = UnmanagedC_createInstance();         UnmanagedC_setMethodHandler(mHandlerInstance, impl_method);         mInstance = C_createInstance();     }      ~C()     {         UnmanagedC_deleteInstance(mHandlerInstance);         C_deleteInstance(mInstance);     }      \/\/... } <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/e8e\/b9a\/b62\/e8eb9ab628a4472495afea24ca6ce1b6.png\"\/><br \/>  \u0422\u0430\u043a\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u043c\u043e\u0436\u043d\u043e \u0441\u043c\u0435\u043b\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0432 managed \u043a\u043e\u0434\u0435, \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c, \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u044b, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043d\u0435\u0433\u043e \u0432 unmanaged \u0441\u0440\u0435\u0434\u0443. \u0414\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043c\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u043b\u0438 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u043c\u044b \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 UnmanagedC. \u042d\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0440\u0430\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e unmanaged \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b unmanaged \u043a\u043b\u0430\u0441\u0441\u0430 C \u0442\u0440\u0430\u043d\u0441\u043b\u0438\u0440\u0443\u044f \u0432\u044b\u0437\u043e\u0432\u044b \u0447\u0435\u0440\u0435\u0437 managed \u043a\u043e\u0434. \u041d\u043e \u0442\u0430\u043a\u043e\u0432\u0430 \u0446\u0435\u043d\u0430 \u0437\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u0432. \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435, \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u0451\u043d\u043d\u043e\u043c \u043a \u0441\u0442\u0430\u0442\u044c\u0435, \u044d\u0442\u043e\u0442 \u0441\u043b\u0443\u0447\u0430\u0439 \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 method \u0443 \u043a\u043b\u0430\u0441\u0441\u0430 D. \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 callstack, \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c:<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/6a3\/01a\/8d1\/6a301a8d10634ef8b585cab0a99f06b4.png\"\/>  <\/p>\n<h2>\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f<\/h2>\n<p>  Platform Invoke \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438 \u0434\u043b\u044f \u043e\u0431\u0445\u043e\u0434\u0430 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043c\u044b \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c \u0438\u0437 \u0441\u0440\u0435\u0434\u044b \u0432 \u0441\u0440\u0435\u0434\u0443, \u043e\u0431\u0451\u0440\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0432 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c. \u041d\u0430 \u0442\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438.<\/p>\n<p>  \u041d\u0430\u043c \u043f\u043e\u0432\u0435\u0437\u043b\u043e. \u041d\u0430\u0448 C++ \u043c\u043e\u0434\u0443\u043b\u044c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 ModuleException \u0438\u043b\u0438 \u0435\u0433\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u0432. \u0422\u0430\u043a \u0447\u0442\u043e \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432\u043e \u0432\u0441\u0435\u0445 \u043c\u0435\u0442\u043e\u0434\u0430\u0445, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043e\u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e. \u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0432 managed \u0441\u0440\u0435\u0434\u0443 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 ModuleException. \u041f\u043e \u0438\u0434\u0435\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043d\u043e \u044f \u043d\u0435 \u0445\u043e\u0447\u0443 \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0442\u0435\u043c\u043e\u0439 \u043c\u0430\u0440\u0448\u0430\u043b\u0438\u043d\u0433\u0430 \u0441\u0442\u0440\u043e\u043a \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u0442\u0430\u043a \u0447\u0442\u043e \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0431\u0443\u0434\u0443\u0442 \u00ab\u043a\u043e\u0434\u044b \u043e\u0448\u0438\u0431\u043e\u043a\u00bb:  <\/p>\n<pre><code class=\"cs\">public sealed class ModuleException : Exception {     IntPtr mInstance;     bool mDelete;      \/\/... \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043e create\/delete instance      [DllImport(&quot;shim&quot;, CallingConvention = CallingConvention.Cdecl)]     private static extern int ModuleException_getCode( IntPtr instance);      public int Code     {         get         {             return ModuleException_getCode(mInstance);         }     }      public ModuleException( int code)     {         mInstance = ModuleException_createInstance(code);         mDelete = true;     }      internal ModuleException( IntPtr instance)     {         Debug.Assert(instance != IntPtr.Zero);         mInstance = instance;         mDelete = false;     }      ~ModuleException()     {         if (mDelete)             ModuleException_deleteInstance(mInstance);     }      \/\/... \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043e getUnmanaged  } <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u043c\u0435\u0442\u043e\u0434 C::method \u043c\u043e\u0436\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 ModuleException. \u041f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439:  <\/p>\n<pre><code class=\"cpp\">\/\/\u0412\u0435\u0441\u044c \u043a\u043b\u0430\u0441\u0441 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u043d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f typedef int (*\u0421_method_ptr )(int arg, ModuleException **error);  int UnmanagedC ::method(int arg ) {     ModuleException *error = nullptr;     int result = m\u0421_method_ptr( arg, &error);     if (error != nullptr)     {         int code = error-&gt;getCode();         \/\/... \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 error \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u043d\u0438\u0436\u0435 \u0438 \u0432 \u0441\u044d\u043c\u043f\u043b\u0435         throw ModuleException(code);     }     return result; } <\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"cpp\">int C_method(C *instance, int arg, ModuleException ** error) {         try        {                return instance-&gt;method( arg);        }         catch ( ModuleException& ex)        {               *error = new ModuleException(ex.getCode());                return 0;        } } <\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"cs\">public class C {     \/\/...      [DllImport(&quot;shim&quot;, CallingConvention = CallingConvention.Cdecl)]     private static extern int C_method(IntPtr instance, int arg, ref IntPtr error);      [UnmanagedFunctionPointerAttribute( CallingConvention.Cdecl)]     private delegate int MethodHandler( int arg, ref IntPtr error);      private int impl_method( int arg, ref IntPtr error)     {         try         {             return method(arg);         }         catch (ModuleException ex)         {             error = ex.getUnmanaged();             return 0;         }     }      public virtual int method(int arg)     {         IntPtr error = IntPtr.Zero;         int result = C_method(mInstance, arg, ref error);         if (error != IntPtr.Zero)             throw ModuleException(error);         return result;     }      \/\/...  } <\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0441 \u0442\u043e\u0436\u0435 \u0436\u0434\u0443\u0442 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u0441 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u0430\u043c\u044f\u0442\u044c\u044e. \u0412 \u043c\u0435\u0442\u043e\u0434\u0435 impl_method \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0443, \u043d\u043e Garbage Collector \u043c\u043e\u0436\u0435\u0442 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0435\u0451 \u0440\u0430\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 \u0432 unmanaged \u043a\u043e\u0434\u0435. \u041f\u043e\u0440\u0430 \u0443\u0436\u0435 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439!  <\/p>\n<h2>\u0421\u0431\u043e\u0440\u0449\u0438\u043a \u043c\u0443\u0441\u043e\u0440\u0430 \u043f\u0440\u043e\u0442\u0438\u0432 \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u043e\u0432<\/h2>\n<p>  \u0422\u0443\u0442 \u043d\u0430\u0434\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043d\u0430\u043c \u0431\u043e\u043b\u0435\u0435-\u043c\u0435\u043d\u0435\u0435 \u043f\u043e\u0432\u0435\u0437\u043b\u043e. \u0412\u0441\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043e\u0442 \u043d\u0435\u043a\u043e\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 IObject, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u044b addRef \u0438 release. \u041c\u044b \u0437\u043d\u0430\u043b\u0438, \u0447\u0442\u043e \u0432\u0435\u0437\u0434\u0435 \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043b\u0441\u044f \u0432\u044b\u0437\u043e\u0432 addRef. \u0418 \u0432\u0441\u044f\u043a\u0438\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0432 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435 \u0438\u0441\u0447\u0435\u0437\u0430\u043b\u0430, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043b\u0441\u044f \u0432\u044b\u0437\u043e\u0432 release. \u0417\u0430 \u0441\u0447\u0451\u0442 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043c\u044b \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0433\u043b\u0438 \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u043d\u0443\u0436\u0435\u043d \u043b\u0438 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c unmanaged \u043c\u043e\u0434\u0443\u043b\u044e \u0438\u043b\u0438 \u043a\u043e\u043b\u0431\u0435\u043a\u0438 \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f managed \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0432 unmanaged \u0441\u0440\u0435\u0434\u0435, \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u044d\u0442\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0432\u044b\u0437\u043e\u0432\u044b addRef \u0438 release \u0438\u0437 unmanaged \u043a\u043e\u0434\u0430 \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0442\u044c managed \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043d\u0443\u0436\u043d\u044b.<\/p>\n<p>  \u0412\u044b\u0437\u043e\u0432\u044b addRef \u0438 release \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u0437 unmanaged \u043a\u043e\u0434\u0430 \u0432 managed, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u2014 \u044d\u0442\u043e \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442 \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0431\u0440\u043e\u0441:  <\/p>\n<pre><code class=\"cpp\">typedef long (*UnmanagedObjectManager_remove )(void * instance); typedef void (*UnmanagedObjectManager_add )(void * instance);  class UnmanagedObjectManager {         static UnmanagedObjectManager mInstance;         UnmanagedObjectManager_remove mRemove;         UnmanagedObjectManager_add mAdd; public:         static void add( void *instance);         static long remove( void *instance);          static void setAdd( UnmanagedObjectManager_add ptr);         static void setRemove( UnmanagedObjectManager_remove ptr); };  UnmanagedObjectManager UnmanagedObjectManager ::mInstance;  void UnmanagedObjectManager ::add(void * instance ) {         if (mInstance.mAdd == nullptr)                return;        mInstance.mAdd( instance); }  long UnmanagedObjectManager ::remove(void * instance ) {         if (mInstance.mRemove == nullptr)                return 0;         return mInstance.mRemove( instance); }  void UnmanagedObjectManager ::setAdd(UnmanagedObjectManager_add ptr ) {        mInstance.mAdd = ptr; }  void UnmanagedObjectManager ::setRemove(UnmanagedObjectManager_remove ptr) {        mInstance.mRemove = ptr; } <\/code><\/pre>\n<p>  \u0412\u0442\u043e\u0440\u043e\u0435, \u0447\u0442\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u044d\u0442\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c addRef \u0438 release \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 IObject \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u043c\u0435\u043d\u044f\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430, \u0445\u0440\u0430\u043d\u044f\u0449\u0435\u0433\u043e\u0441\u044f \u0432 managed \u043a\u043e\u0434\u0435:  <\/p>\n<pre><code class=\"cpp\">template &lt;typename T &gt; class TObjectManagerObjectImpl : public T {     mutable bool mManagedObjectReleased; public:     TObjectManagerObjectImpl()         : mManagedObjectReleased( false)     {     }      virtual ~TObjectManagerObjectImpl()     {          UnmanagedObjectManager::remove(getInstance());     }      void *getInstance() const     {         return ( void *) this;     }      virtual void addRef() const     {         UnmanagedObjectManager::add(getInstance());     }      virtual bool release() const     {         long result = UnmanagedObjectManager::remove(getInstance());         if (result == 0)             if (mManagedObjectReleased)                 delete this;         return result == 0;     }      void resetManagedObject() const     {         mManagedObjectReleased = true;     } }; <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043b\u0430\u0441\u0441\u044b UnmanagedB \u0438 UnmanagedC \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 TObjectManagerObjectImpl. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 UnmanagedC:  <\/p>\n<pre><code class=\"cpp\">class UnmanagedC : public TObjectManagerObjectImpl &lt;C&gt; {     \u0421_method_ptr m\u0421_method_ptr; public:     UnmanagedC();     void setMethodHandler( \u0421_method_ptr ptr);     virtual int method( int arg);     virtual ~UnmanagedC(); }; <\/code><\/pre>\n<p>  \u041a\u043b\u0430\u0441\u0441 C \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 IObject, \u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u0435\u0442\u043e\u0434\u044b addRef \u0438 release \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043a\u043b\u0430\u0441\u0441\u043e\u043c TObjectManagerObjectImpl, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u043e\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 managed \u0441\u0440\u0435\u0434\u0435.<br \/>  \u041f\u043e\u0440\u0430 \u0431\u044b \u0443\u0436\u0435 \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u043d\u0430 \u043a\u043e\u0434 \u0441\u0430\u043c\u043e\u0433\u043e \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430:  <\/p>\n<pre><code class=\"cs\">internal static class ObjectManager {     \/\/... \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0451, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0441\u043c. \u0441\u044d\u043c\u043f\u043b      private static AddHandler mAddHandler;     private static RemoveHandler mRemoveHandler;      private class Holder     {         internal int count;         internal Object ptr;     }      private static Dictionary&lt; IntPtr, Holder&gt; mObjectMap;      private static long removeImpl( IntPtr instance)     {         return remove(instance);     }      private static void addImpl(IntPtr instance)     {         add(instance);     }      static ObjectManager()     {         mAddHandler = new AddHandler(addImpl);         UnmanagedObjectManager_setAdd(mAddHandler);         mRemoveHandler = new RemoveHandler(removeImpl);         UnmanagedObjectManager_setRemove(mRemoveHandler);          mObjectMap = new Dictionary&lt;IntPtr , Holder &gt;();     }      internal static void add(IntPtr instance, Object ptr = null)     {         Holder holder;         if (!mObjectMap.TryGetValue(instance, out holder))         {             holder = new Holder();             holder.count = 1;             holder.ptr = ptr;             mObjectMap.Add(instance, holder);         }         else         {             if (holder.ptr == null && ptr != null)                 holder.ptr = ptr;             holder.count++;         }     }      internal static long remove(IntPtr instance)     {         long result = 0;         Holder holder;         if (mObjectMap.TryGetValue(instance, out holder))         {             holder.count--;             if (holder.count == 0)                 mObjectMap.Remove(instance);             result = holder.count;         }         return result;     } } <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u041f\u0435\u0440\u0435\u0434 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 managed \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 unmanaged \u0441\u0440\u0435\u0434\u0443, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440. \u0422\u0430\u043a \u0447\u0442\u043e \u043c\u0435\u0442\u043e\u0434 getUnmanaged \u0443 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 AB \u0438 C \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c. \u041f\u0440\u0438\u0432\u0435\u0434\u0443 \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 C:  <\/p>\n<pre><code class=\"cs\">internal IntPtr getUnmanaged() {     ObjectManager.add(mHandlerInstance, this);     return mHandlerInstance; } <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0431\u044b\u0442\u044c \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043b\u0433\u043e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e.<\/p>\n<p>  \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0443 \u043c\u043e\u0434\u0443\u043b\u044f, \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b, \u0437\u0430\u043c\u0435\u043d\u0438\u0432 \u0432\u0441\u0435 \u0432\u044b\u0437\u043e\u0432\u044b ClassName_deleteInstance \u043d\u0430 \u0432\u044b\u0437\u043e\u0432\u044b IObject::release, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c \u0434\u0435\u043b\u0430\u0442\u044c IObject::addRef \u0442\u0430\u043c, \u0433\u0434\u0435 \u044d\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u0435\u0436\u0434\u0435\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f ModuleException, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0441\u0431\u043e\u0440\u0449\u0438\u043a \u043c\u0443\u0441\u043e\u0440\u0430 \u0443\u0434\u0430\u043b\u0438\u0442 managed \u043e\u0431\u0451\u0440\u0442\u043a\u0443, unmanaged \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440, \u0431\u0443\u0434\u0443\u0447\u0438 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u043c IObject, \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0451\u043d, \u043f\u043e\u043a\u0430 unmanaged \u043c\u043e\u0434\u0443\u043b\u044c \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u0438 \u043d\u0435 \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u0434\u043b\u044f \u043d\u0435\u0451 IObject_release.  <\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u043f\u043e\u043a\u0430 \u043c\u044b \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0435\u0439 \u043c\u043e\u0434\u0443\u043b\u044f, \u043c\u044b \u0438\u0441\u043f\u044b\u0442\u0430\u043b\u0438 \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043c\u043e\u0446\u0438\u0439, \u0432\u044b\u0443\u0447\u0438\u043b\u0438 \u043d\u0435\u043c\u0430\u043b\u043e \u043d\u0435\u0446\u0435\u043d\u0437\u0443\u0440\u043d\u044b\u0445 \u0441\u043b\u043e\u0432 \u0438 \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0441\u043f\u0430\u0442\u044c \u0441\u0442\u043e\u044f. \u041d\u0430\u0432\u0435\u0440\u043d\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0445\u043e\u0442\u0435\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043a\u043e\u043c\u0443-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u043b\u0430\u0441\u044c, \u043d\u043e \u043d\u0435 \u0434\u0430\u0439 \u0431\u043e\u0433. \u041a\u043e\u043d\u0435\u0447\u043d\u043e \u0440\u0435\u0448\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u044c\u044e, \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0431\u044b\u043b\u043e \u0432\u0435\u0441\u0435\u043b\u043e. \u041d\u043e \u043c\u044b \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 \u0438 \u0431\u044b\u043b\u043e \u0432 \u043d\u0438\u0445 \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443. \u042d\u0442\u043e \u0431\u044b\u043b \u0442\u0435\u0441\u0442 \u043d\u0430 \u0432\u044b\u043d\u043e\u0441\u043b\u0438\u0432\u043e\u0441\u0442\u044c.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b, \u0432\u0441\u0451 \u0436\u0435, \u0441\u0442\u043e\u043b\u043a\u043d\u0451\u0442\u0435\u0441\u044c \u0441 \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439, \u0442\u043e \u0432\u043e\u0442 \u0432\u0430\u043c \u0441\u043e\u0432\u0435\u0442: \u043b\u044e\u0431\u0438\u0442\u0435 Sublime Text, \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u0441\u043d\u0438\u043f\u043f\u0435\u0442\u044b. \u042d\u0442\u043e\u0442 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u0443\u0431\u0435\u0440\u0451\u0433 \u043d\u0430\u0441 \u043e\u0442 \u0430\u043b\u043a\u043e\u0433\u043e\u043b\u0438\u0437\u043c\u0430.<\/p>\n<p>  P.S. \u0420\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 <a href=\"https:\/\/github.com\/simbirsoft-public\/pinvoke_example\">github.com\/simbirsoft-public\/pinvoke_example<\/a>               <\/p>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habrahabr.ru\/post\/276011\/\"> https:\/\/habrahabr.ru\/post\/276011\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u043f\u043e\u043b\u043d\u0430\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f C++ \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0432 managed \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Platform Invoke. \u041f\u043e\u0434 \u043f\u043e\u043b\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0435\u0439 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0435\u0451 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432 (\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 managed \u043a\u043e\u0434\u0435 \u043a\u0430\u043a \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b). \u042d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u00ab\u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u00bb \u0432 unmanaged \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-273114","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/273114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=273114"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/273114\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=273114"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=273114"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=273114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}