是否可以从 C# 应用程序连接到 32 位 C++ RPC 服务器应用程序

Posted

技术标签:

【中文标题】是否可以从 C# 应用程序连接到 32 位 C++ RPC 服务器应用程序【英文标题】:Is it possible to connect to a 32 bit C++ RPC Server application from a C# application 【发布时间】:2020-04-13 19:21:20 【问题描述】:

让我尝试简要解释一下我在这里要完成的工作......

我使用远程过程调用 (RPC) 方法在 C++ 中开发了一个客户端应用程序,并在 C++ 中开发了一个服务器应用程序。客户端是 64 位的,服务器是 32 位的。这项工作的目标是使用客户端将变量传递给服务器端的函数。然后服务器将使用 32 位 .dll 来处理接收到的数据并将输出的值返回给客户端。这个过程运行良好,我对此非常满意。

我正在使用一个用 C# 开发的 64 位应用程序,它有一个用于将变量发送到 .dll 并返回输出值的静态类。由于此应用程序是 64 位的,因此无法连接到这些计算所需的 32 位 .dll (duh)。

现在我的问题...

有什么方法可以保留我已经用 C++ 开发的流程并从 64 位 C# 项目访问 32 位服务器?有没有更好的方法来解决这一切?

编辑: 我还应该包括我正在使用 rpcrt4.lib,这是我的客户端示例代码。

int main()
 
    RPC_STATUS status;
    unsigned char* szStringBinding = NULL;
    char temppath[MAX_PATH] = 0;

    // Creates a string binding handle.
    // This function is nothing more than a printf.
    // Connection is not done here.
    status = RpcStringBindingCompose(
    NULL, // UUID to bind to.
    reinterpret_cast<unsigned char*>("ncacn_ip_tcp"), // Use TCP/IP

    // protocol.
    reinterpret_cast<unsigned char*>("localhost"), // TCP/IP network

    // address to use.
    reinterpret_cast<unsigned char*>("4747"), // TCP/IP port to use.
    NULL, // Protocol dependent network options to use.
    &szStringBinding); // String binding output.

    if (status)
      exit(status);

    // Validates the format of the string binding handle and converts
    // it to a binding handle.
    // Connection is not done here either.
    status = RpcBindingFromStringBinding(
    szStringBinding, // The string binding to validate.
    &hRPCProjectBinding); // Put the result in the implicit binding
                          // handle defined in the IDL file.

    if (status)
        exit(status);

     RpcTryExcept
     

      // Calls the RPC function. The hRPCProjectBinding binding handle
      // is used implicitly.
      // Connection is done here.
      Output((unsigned char*)"Implcicit RPC Server Call from Client "); 

      system("PAUSE");

      ShutDown();


     
     RpcExcept(1)
     
       std::cerr << "Runtime reported exception " << RpcExceptionCode()
        << std::endl;
     
     RpcEndExcept

    // Free the memory allocated by a string.
    status = RpcStringFree(
        &szStringBinding); // String to be freed.

    if (status)
      exit(status);

   // Releases binding handle resources and disconnects from the server.
   status = RpcBindingFree(
   &hRPCProjectBinding); // Frees the implicit binding handle defined in
                                                // the IDL file.

  if (status)
      exit(status);

这是我开发这个项目所遵循的教程:

Introduction to RPC - part 1

非常感谢任何参考资料、输入或批评。

感谢您抽出宝贵时间阅读本文并提供任何指导。

【问题讨论】:

您应该指定您正在使用的 RPC 框架,可能会给我们几行客户端和服务器代码,以查看示例调用。据我所知,还没有 std::rpc_call ;-) 哈哈@Jeffrey 明白了,我很抱歉。坚持住。 您不能在同一进程中混合使用 32 位和 64 位代码。您需要一个 32 位进程来加载您的 32 位 DLL。假设我正确理解您的情况,听起来您可以构建一个包装器并使用一些 IPC 机制从您的 64 位服务器与其通信。 @MilesBudnek 服务器已经是 32 位,客户端是 64 位。我正在使用上面解释的方法来获取 32 位 .dll 的值,并将输出返回给我的 C++ 客户端,它正在工作。我需要将功能转移到 C# 应用程序。我一直在研究使用包装器,我认为这就是我将要采取的路线。 【参考方案1】:

假设您在谈论 MS-RPC,最简单的方法是用 C++ 编写一个互操作 DLL,以进行 RPC 调用。让该 DLL 包含 midl.exe 的 *_c.c 和 *_h.h 输出,然后添加代码以设置绑定句柄等。

这将需要在 C++ 代码中进行大量翻译(从 .net 类型到可以跨网络传输的类型),但需要最少的直接努力。

更极端的选择是将您的 RPC 代码重写为纯 .net,此时有很多可用的远程处理选项。

【讨论】:

@SoroneIHaetir 我正在考虑使用互操作和包装,并已开始构建该 .dll。如果这种方法是最好的方法,我只是想获得一些想法。

以上是关于是否可以从 C# 应用程序连接到 32 位 C++ RPC 服务器应用程序的主要内容,如果未能解决你的问题,请参考以下文章

从 32 位 C# 到 64 位 C++ 的 PostMessage 参数

需要连接到 C++ DLL

从 64 位 php 网站强制连接到 32 位访问数据库

如何将 C++ dll 连接到 C# 项目?

无法使用 C# 从 Xamarin.iOs 和 Xamarin.Android 连接到 MySql

将 64 位 Java 应用程序连接到 32 位 ODBC 驱动程序