我可以将 char* 数组而不是几个参数传递给函数吗?

标签 c dynamic-linking

我正在尝试编写一个程序,该程序将运行动态库中的函数,其名称、参数及其类型由用户输入。我可以使用 dlsym(func_name) 得到一个指向这个函数的 void* 指针,但是我事先不知道参数的类型和它们的数量,所以我不能以正常的方式取消引用这个指针。

如果我将所有参数的字节表示复制到一个 char * 数组中,我可以调用一个函数并以此数组作为参数吗?例如,当在程序集中调用 printf 时,我可以将参数和格式字符串压入堆栈并调用 printf。也许我可以在 C 中做类似的事情,或者使用程序集插入?

例如,假设函数是 void func(int, double); 我得到参数 int adouble b .然后我会创建一个数组:

char buf[sizeof(int) + sizeof(double)]
memcpy(buf, &a, sizeof(int))
memcpy(buf + sizeof(int), &b, sizeof(double))

并将其用作压入堆栈的参数。

用户输入函数的名称、描述其类型的字符串以及参数本身。例如:

func_name
viid
5
6
2.34

func_name 是将在 dlsym 中使用的函数的名称。 viid 表示该函数具有 void func_name(int, int, double) 类型(第一个 char 是返回类型,其余是参数。v = void, i = int, d = double)。其余为参数。

最佳答案

不,除了可能在纯粹在堆栈上传递参数的 ABI 中。任何计算环境都有如何传递参数的规范。 (此规范是平台的应用程序二进制接口(interface) [ABI] 规范的一部分。)参数类型和大小会影响它们是在通用寄存器、浮点寄存器还是其他位置传递,以及它们如何对齐。很少(如果有的话)这样的规范将参数作为字节的原始转储传递到堆栈。

可以编写代码来解码参数的描述并构造调用函数所需的状态。这样的代码至少需要部分用汇编或各种语言扩展来编写。 (我希望有些人可能已经编写了这样的代码并使其可用,但没有这样的引用。)对于大多数情况来说,这可能是一个实现起来成本过高的解决方案;您应该寻求替代方法来实现您的基本目标。

如果 ABI 确实指定所有参数都放在堆栈上,则可以在包含 unsigned char 数组的结构中传递任意参数:

  • 必须确定最大大小,例如 struct { unsigned char bytes[128]; },因为标准 C 不支持可变大小的结构。
  • 对于具有最严格对齐的任何参数,结构必须按照要求对齐。
  • 所有参数的字节必须在结构内正确对齐。
  • 函数将通过将结构本身作为参数传递来调用。请注意,ABI 必须说明即使是大型结构也会直接在堆栈上传递。有人可能会说传递了指向结构(的副本)的指针。

请注意,ABI 可能包含影响函数调用的其他细节,例如规定某个寄存器必须包含参数的数量或以某种方式设置,即使它本身不包含参数也是如此。

关于我可以将 char* 数组而不是几个参数传递给函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61375829/

相关文章:

c - 检查指针数据时出现段错误

Linux 上的 CMake : "target platform does not support dynamic linking"

在 Linux 上动态链接到 libc 时调用 `atexit`

javascript - 动态符号检索错误: Win32 error 127 - even when importing self process

c++ - Qt - 帮助链接动态库

c - 错误 : initializer element is not constant in assigning structure pointers

用作函数参数时,Char 数组大小会发生变化

C fread/fwrite 在处理换行符时表现得很奇怪

c++ - 有没有办法在 UBUNTU 中的大型库文件夹(.a 和 .so 文件)中搜索函数?

cmake - 针对非标准位置中的库编译 CMake 项目