没有 stub 的 C RPC

标签 c rpc

我有这个程序,我希望其他进程能够调用函数(通过 unix 套接字)。消息协议(protocol)非常简单,函数名称、函数签名和保存参数的缓冲区 (char *)。

当我程序中的一个模块想要允许访问一个函数时,它会在库中注册名称和签名。我面临的问题是一旦收到请求就实际调用该函数。我看过 RPC 和 java RMI 类库,但那些需要我生成 stub 来包装调用。我正在处理的系统非常动态,我还必须与我无法修改的其他人的代码进行交互。

所以基本上,一个函数可能看起来像:

int somefunc(int someparam, double another)
{
    return 1234;
}

现在我在图书馆注册:

//           func ptr   name       signature
REG_FUNCTION(somefunc, "somefunc", "i:id");

当请求进来时,我会做一些错误检查,一旦有效我想调用该函数。所以我有变量:

void * funcptr = (the requested function);
char * sig = (the function signature);
char * params = (a buffer of function parameters);
//note that the params buffer can hold data types of arbitrary lengths

如何在C语言中调用带有参数的函数?

谢谢!

最佳答案

我认为这通常无法完全解决,仅使用 C。例如,您不知道目标函数使用的调用约定。您有可能最终“欺骗”编译器,或者至少不得不事后猜测它。如果编译器决定使用在寄存器中传递的参数来构建注册函数,可能是由于某些优化设置(或者如果它是用不同的编译器构建的怎么办?)。

通常也没有办法在 C 中表达您想要使用给定参数集调用函数,并且参数的值需要从随机字节缓冲区中解压缩。

你可以做这样可怕的事情:

enum { VOID_INT, VOID_INT_DOUBLE, VOID_DOUBLE_INT, ... } Signature;

void do_call(const void *userfunction, const void *args, Signature sig)
{
  switch(signature)
  {
    case VOID_INT:
    {
      int x = *(int *) args;
      void (*f)(int) = userfunction;
      f(x);
      break;
    }
    case VOID_INT_DOUBLE:
    ...
  }
}

但很明显,这与可扩展性并不存在于同一个大陆。对于一些合理的返回类型和参数类型集,您当然可以自动生成此代码。对于将函数指针转换为 void * 或从中转换函数指针,您仍然有点不感冒,但这可能是可以接受的。不过,您仍然总是冒着有人给您签名而您没有预生成代码的风险。

关于没有 stub 的 C RPC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/733059/

相关文章:

c - 不明白为什么 strstr 函数返回非 NULL 值

postgresql - 使用 bitcoind RPC 和 API 填充 PostgreSQL 数据库

c# - 需要用C#写的RPC调用例子

java - 我可以(轻松地)使用第三方库来处理 Java RMI 的序列化吗?

c - 如何通过 RPC 发送数组?

用于启动软件安装的 RPC 命令

c - 显示单链表内容,退出时代码崩溃

c++ - C/C++ 中注释行末尾的反斜杠

c++ - 解码字符数组

使用 C 控制客户端-服务器机制