[英]Communicating between C# and Visual C++ over IPC port (OR: Sharing a type between a Visual C++ DLL and a C# application)
我有一個用Visual C ++編寫的DLL和一個用C#編寫的應用程序。 用C#編寫的應用程序已經在其多個實例之間使用了IPC,因此它只能運行一個實例(它嘗試啟動IPC服務器,如果不能假設已經有一個正在運行,則在這種情況下,它將發送IPC到現有應用程序的命令行參數)。
現在,我想從Visual C ++發送命令,但是,即使我在Visual C ++中創建與C#中的類型定義匹配的類型定義(在實現級別上),它也會拒絕連接,因為它們從根本上還是兩種不同的類型(從兩個不同的程序集)。
我曾考慮過在Visual C ++中使用Reflection來從C#程序集中獲取類型,但是我不能這樣做,因為那樣的話,我必須將程序集與DLL一起運送(這違背了DLL作為API的目的。應用程序)。
除了將類存儲在另一個DLL中並使該應用程序和API DLL都引用該類之外,我不確定是否可以實現此目的,但這並不是理想的解決方案,因為d像要分發的單個API DLL。
關於如何通過IPC連接(不允許其他形式的通信,如TCP)將請求發送到應用程序,有什么建議嗎?
解決方案是將InterProcess類放置在API DLL中,並使C#應用程序使用DLL作為引入該類的引用。
同樣重要的是要注意,為了正確地初始化共享庫,我必須在單獨的AppDomain中初始化共享的服務器端,並使C#應用程序成為這樣的客戶端(這是先前粘貼的新版本) :
try
{
// Set up an interprocess object which will handle instructions
// from the client and pass them onto the main Manager object.
this.m_ServerDomain = AppDomain.CreateDomain("roketpack_server");
this.m_ServerDomain.DoCallBack(() =>
{
// We must give clients the permission to serialize delegates.
BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider();
serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
IpcServerChannel ipc = new IpcServerChannel("roketpack", "roketpack", serverProv);
ChannelServices.RegisterChannel(ipc, true);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(API.InterProcess),
"InterProcessManager",
WellKnownObjectMode.Singleton);
});
// Now initialize the object.
IpcClientChannel client = new IpcClientChannel();
ChannelServices.RegisterChannel(client, true);
this.m_InterProcess = (API.InterProcess)Activator.GetObject(
typeof(API.InterProcess),
"ipc://" + name + "/InterProcessManager");
InterProcessHandle.Manager = this;
this.m_InterProcess.SetCalls(InterProcessHandle.CallURL,
InterProcessHandle.IsLatestVersion,
InterProcessHandle.RequestUpdate);
return true;
}
catch (RemotingException)
{
// The server appears to be already running. Connect to
// the channel as a client and send instructions back
// to the server.
IpcClientChannel client = new IpcClientChannel();
ChannelServices.RegisterChannel(client, true);
API.InterProcess i = (API.InterProcess)Activator.GetObject(
typeof(API.InterProcess),
"ipc://" + name + "/InterProcessManager");
if (i == null)
{
Errors.Raise(Errors.ErrorType.ERROR_CAN_NOT_START_OR_CONNECT_TO_IPC);
return false;
}
if (Environment.GetCommandLineArgs().Length > 1)
i.CallURL(Environment.GetCommandLineArgs()[1]);
return false;
}
我希望這個解決方案可以幫助其他人:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.