[英]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.