繁体   English   中英

通过IPC端口在C#和Visual C ++之间进行通信(或:在Visual C ++ DLL和C#应用程序之间共享类型)

[英]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#应用程序使用DL​​L作为引入该类的引用。

同样重要的是要注意,为了正确地初始化共享库,我必须在单独的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM