1

我有一个名为 testdynamic 的函数,它使用 dlopen 和 dlsym 动态调用。现在,我创建了一个结构:

typedef struct BigStruct{
    char el[2000];
}BigStruct;

它用于存储函数的参数。然后,我将空间分配给一个名为:

void *cur = (void*)malloc(totalSize);

其中,totalSize 是参数的大小。我事先有这个信息。

之后,我将所有参数复制到 cur。

然后,我将它转换为 BigStruct,如下所示:

BigStruct *bg;
bg = (BigStruct*)cur;

并像这样运行它:

void* ch = (void*)testdynamic(*bg);

现在,当我打印参数时,在函数 testdynamic 中,我得到了所有数据类型(如char**int*、 int 等)的正确值。

唯一不起作用的数据类型是 char*。即使在使用 调用函数之前*bg,bg->el 的内容对于 char* 也是正确的。但是,调用后,出现错误。

可能是什么问题呢?

这是testdynamic的代码

char* testdynamic(char* x, char* y){
    printf("%s %s\n", x, y);
    return "hello";
}

我想从我的代码中将参数传递给函数 testdynamic。
这个 testdynamic 可以是可以接受任何类型的任何参数的任何函数。
我在运行时获得有关该函数的信息。由于 char* 的大小为 1,我将所有内容都转换为 char*,然后将其传递给函数。
此时,如果我在 testdynamic 中打印任何类型为char*.

4

6 回答 6

0

这仅适用于大小为sizeof(BigStruct)

您不能假设结构是其内容的大小,因为编译器可能会假设对齐等。

如果您只想要20,000 charsBigStruct ,然后像其他人建议的那样将其 malloc 。

于 2013-08-05T18:10:45.027 回答
0

To provide accurate, non-opinionated comments, a copy of the code is required. Thus, I have taken your comments and produced the following code. It is probably NOT what you want to do. However, a programming problem should be approached in steps or increments.

That is, get something simple to work and then make it a little more complex, but still working, and work towards your final version. This is how many of us work. No one is able to write a complex program correctly the first time, especially if new to the language!

#include <stdio.h>
#include <stdlib.h>
char *testdynamic(char *x, char* y){

        printf("%s %s\n", x, y);
        return "hello";
    }

main()
{
    typedef struct BigStruct{
        char el[2000];
    } BigStruct;

    char      *ret_char_ptr;

    BigStruct *bg;

    char x[] = "abcd";
    char y[] = "23456";

    bg = malloc(sizeof(BigStruct));

    // invoke the testdynamic function
    ret_char_ptr = testdynamic(x, y);


    printf("%s\n", ret_char_ptr);

}

I ran this code on Eclipse/Microsoft C compiler and got the following output:

abcd 23456
hello

Note. BigStruct has yet to used in this code. Not sure what your intent is, but C does provide a way to pass parameter lists that vary in length and data from several different calls to the same function.

于 2013-08-05T18:53:35.230 回答
0

您假设 BigStruct 看起来与 2000 个字符的数组完全一样。这取决于编译器,不太可能是真的。我猜您真的想将 cur 指向的数据复制到 el 数组中,而不是将其全部写入 BigStruct 本身,因为 BigStruct 本身将具有一些您不知道的内部存储格式。

于 2013-08-05T17:41:09.313 回答
0

又读了几遍之后......

您正在为需要 2 个参数的函数传入一个参数。

您是否使用 -Wall 在编译期间将警告视为错误?第二个参数没有传入,即参数 y 为空。访问 null 会导致问题。

于 2013-08-05T18:18:44.263 回答
0

所以总结一下我理解你在做什么:

  • 将 cur 视为 char* 并将参数列表复制到其中
  • 将 cur 转换为 BigStruct*,然后将其传递给 testdynamic 函数。

在我看来,这似乎是一种奇怪的处理方式,如果不查看 testdynamic 函数内部,我会猜测这就是导致错误的原因。我建议更改您对 BigStruct 的定义:

typedef struct {
    char * el;
} BigStruct;

这样,您可以为 char 数组分配空间,将参数列表复制到其中,然后将 BigStruct 中的 char * 设置为指向相关的内存块,如下所示:

char * cur = malloc(totalSize);
// Copy parameters over into cur
BigStruct * bg = malloc(sizeof(BigStruct));
bg->el = cur;

然后再次调用您的 testdynamic 函数。试试这个,你还会遇到运行时错误吗?

编辑:看到了 testdynamic 函数的内容,我可以看到它的几个问题

char* testdynamic(char* x, char* y){
    printf("%s %s\n", x, y);
    return "hello";
}
  1. 该函数接受 2 char * 但您似乎只在代码中传递了 1。如果你只给它一个 x 的参数,它应该为 y 打印什么?
  2. 假设您现在正在为 x 和 y 传递参数。您确定两个字符串都以空字符结尾吗?printf 通过打印字符来工作,直到找到 '\0' 字符。
  3. 您不能只从这样的函数中返回字符串文字。该字符串文字属于该函数,一旦函数返回,您无法保证保存该字符串的内存仍然可以安全地再次访问。如果你想返回一个这样的字符串,你应该首先为字符串分配 malloc() 空间并将地址返回到分配的内存块。
于 2013-08-05T18:01:35.237 回答
0

如果totalSize > sizeof(BigStruct)您没有将完整的数据副本传递给您testdynamic(),则可能会弄乱副本并因此导致未定义的行为

如果totalSize < sizeof(BigStruct),当您将 *bg 传递给时,您在读取不属于您的内存空间时遇到问题testdynamic()- 因此存在未定义的行为

只需使用,您就更安全了

bg = malloc(*bg);

这里还有其他有问题的程序问题,但需要更完整的帖子。

于 2013-08-05T18:06:56.077 回答