Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以将char*数组而不是几个参数传递给函数吗?_C_Dynamic Linking - Fatal编程技术网

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

我可以将char*数组而不是几个参数传递给函数吗?,c,dynamic-linking,C,Dynamic Linking,我正在尝试编写一个程序,该程序将从动态库中运行函数,并由用户输入函数的名称、参数及其类型。我可以使用dlsym(func_name)获取指向此函数的void*指针,但是我事先不知道参数的类型及其数量,因此无法以正常方式取消引用此指针 如果我将所有参数的字节表示形式复制到一个char*数组中,我可以用这个数组作为参数调用函数吗?例如,在汇编中调用printf时,我可以将参数和格式字符串推送到堆栈中,并调用printf。也许我可以在C中做类似的事情,或者使用程序集插入 例如,假设函数是void fu

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

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

例如,假设函数是
void func(int,double)和我被赋予参数
inta
double 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)
type(第一个字符是返回类型,其余是参数。v=void,i=int,d=double)。其余的是参数。

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

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

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

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

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

我相信可以通过强制转换以某种方式完成。尝试以char数组的形式发送参数,并将其转换为实际类型进行读取。这件事需要一些试验,直到成功。但是,如果在获得参数后,您仍然不知道参数的类型,这可能是一个问题,因为您不知道如何读取参数。也许您应该发送更多的参数来解释其他参数的类型。不一定是大小,而是类型。像FP这样的不同类型可能使用不同的堆栈。我不认为你真的可以这样做。有些变量在寄存器中传递,有些在堆栈中传递,这取决于数据类型。您可能希望阅读以下内容:@OP Try
libffi
如果我将问题限制在i386 Linux上怎么办?根据这一点,函数调用约定是所有参数都以相反的方式在堆栈上传递order@Binabil:也许吧。如果所有参数都在堆栈上传递,那么传递一个
char
数组将是不同的-C将数组转换为指针并传递该指针。如果参数正确地定位在包含
无符号字符数组的结构(具有正确的对齐方式)中,则这种混乱可能会起作用。但是标准C没有可变长度的结构,所以您需要设置最大大小。假设所有参数一起可以占用最大字节数。我如何将这样的结构传递给函数?只需指向结构的指针就可以了?就像struct Mystr x是我的结构一样,我应该使用((void()(struct Mystr))sym)(&x)调用函数?(假设函数返回类型为void)?