3

我正在尝试从 C++ 运行 libtcc 以使用 C 作为运行时脚本语言。运行时编译的代码必须能够从外部代码运行函数。这在传递整数时工作正常,但是当将结构从 tcc 代码传递到 gcc 代码时,会发生奇怪的事情。

最小运行示例:

#include <libtcc.h>
#include <stdio.h>
struct Vec {
    int x;
};
void tmp(struct Vec test) {
    printf("got %x\n",test.x);
}
int main() {
    TCCState* tcc; tcc = tcc_new();
    tcc_set_output_type(tcc, TCC_OUTPUT_MEMORY);
    tcc_add_symbol(tcc, "tmp", (void*)&tmp);
    tcc_compile_string(tcc, "\
        struct Vec {int x;};\
        void tmp(struct Vec test);\
        void fun() {\
            struct Vec x = {0};\
            tmp(x);\
        }");
    tcc_relocate(tcc, TCC_RELOCATE_AUTO);
    void (*fun)(void) = (void(*)())tcc_get_symbol(tcc, "fun");
    fun();
}

运行:

gcc -ltcc -ldl test.c && ./a.out
> got 23b472b0
tcc -ltcc -ldl test.c && ./a.out
> got 0

为什么 gcc 编译后的版本不打印预期的 0?当我只将long longs 而不是 int 放入结构时,它可以工作。输出任何其他数据类型和随机内容。

起初我认为这是因为对齐或其他原因,但在结构中仅使用单个变量时也会发生这种情况。

我正在使用 Linux 3.16 x86_64 和 tcc 0.9.26

4

2 回答 2

4

似乎问题集中在 C 和 C++ 将整个“struct Vec 测试”理解为参数的方式上。在 TCC 中,它被视为/假定为指针。在 C++ 中,看起来必须更清楚地说明它是一个指针。

#include libtcc.h
#include stdio.h
struct Vec {
    int x;
};
void tmp(struct Vec * test) {
    printf("got %x\n",test->x);
}
int main() {
    TCCState* tcc; tcc = tcc_new();
    tcc_set_output_type(tcc, TCC_OUTPUT_MEMORY);
    tcc_add_symbol(tcc, "tmp", (void*)&tmp);
    tcc_compile_string(tcc, "\
        struct Vec {int x;};\
        void tmp(struct Vec test);\
        void fun() {\
            struct Vec x = {5};\
            tmp(x);\
        }");
    tcc_relocate(tcc, TCC_RELOCATE_AUTO);
    void (*fun)(void) = (void(*)())tcc_get_symbol(tcc, "fun");
    fun();
}

输出显示为:

got 5
于 2014-10-23T22:49:31.593 回答
1

在来自官方 git 存储库的新版本 tcc (libtcc) 中,它按预期工作(打印“得到 0”)。在 gcc 4.9.3 和 tcc 0.9.26(提交 00ba4b)上测试。

于 2015-10-07T17:30:47.150 回答