簡體   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