我试图从C ++运行libtcc以使用C作为运行时脚本语言。运行时编译的代码必须能够从外部代码运行函数。 传递int时这很好用,但是当把结构从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 long
s而不是ints放入结构中时,它可以工作。输出任何其他数据类型和随机内容。
起初我认为这是因为对齐或其他原因,但在结构中只使用一个变量时也会发生这种情况。
我使用Linux 3.16 x86_64和tcc 0.9.26
答案 0 :(得分:3)
问题似乎在于C和C ++理解整个&#34; struct Vec test&#34;作为参数。在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
答案 1 :(得分:1)
在官方git存储库的新版本的tcc(libtcc)中,它按预期工作(打印&#34;得到0&#34;)。在gcc 4.9.3和tcc 0.9.26(commit 00ba4b)上测试。