C#有時候因為效能因素,需要和原生C++做溝通,這時候必須透過C++/Cli這個Bridge來做轉換,將受到Manage的Object轉換為Native的Object.
如架構圖所示,C#可以透過C++/Cli的介面操作,而再由C++/Cli再將Manage的介面轉換為Native的介面.最後NativeC++再直接使用由C++/Cli所提供的Native介面 (此時C++/Cli所提供的Native介面就不能包含Manage的Code)
下圖為架構圖:
Fig 1. 架構圖
而在實際的作法上,可以先使用C++/Cli Create一個Native的.h檔案,然後宣告一個無型別指標(Void*)用來存放C#的物件.再透過C++/Cli使用ManagePointer(^) new出一個C#的物件,並將Native Pointer(*)指向C# Object(^).
這時候,不管Native C++要使用任何的C#function,只要先將NativePointer(*)轉換成ManagePointer(^)就可以操作C#了.
而C#若要Send Event過去給Native C++,一樣需要先透過C++/Cli將C#的 EventHandle加入Manage的Event,然後在轉成Native的Event丟給Native C++.
基本上轉換的過程中,都是透過ManagePointer和NativePointer互傳.
下圖為運作架構圖:
Fig 2. 運作架構圖
最後附上簡易的 Bridge Sample Code
Sample Code
------------------------Native C PlusPlus.h----------------------
define DECLSPECIFIER __declspec(dllexport)
define EXPIMP_TEMPLATE
typedef void(__stdcall *CallbackType)(void*, void*);
namespace NativeToMangeBridge
{
[event_source(native)]
class DECLSPECIFIER Bridge
{
Public:
void callCSfunction(std::stringmessage);
__event void OnEventInvoke(CallbackType callback);
void * m_ptr;
}
}
----------------------------------------------------------------------
------------------------Native/Cli.cpp-----------------------------
#include "Native C Plus Plus .h"
namespace NativeToMangeBridge
{
Bridge::Bridge()
{
CSharpClass^ _CSInstances = gcnew CSharpClass();
m_impl= GCHandle::ToIntPtr(GCHandle::Alloc(_CSInstances)).ToPointer();
}
voidBridge::callCSfunction(std::string message)
{
GCHandle handle = GCHandle::FromIntPtr(IntPtr(m_ptr));
CSharpClass^ _CSPtr = safe_cast<CSharpClass^>(handle.Target);
String^ MgrMessage = gcnew String(message.c_str());
_CSPtr->CSfunction(MgrMessage);
}
}
----------------------------------------------------------------------
------------------------Cli.cpp--------------------------------------
namespace NativeToMangeBridge
{
Cli::Bridge(Bridge _NativeCPlus)
{
_CSPtr->InfoChangeEvent += gcnew EventHandler<CSharpClass::EventHandler^>(this, &Cli::function);
}
Cli::function()
{
__raise NativeCPlus->OnEventInvoke(_Callbackfunction);
}
}
----------------------------------------------------------------------