2014-10-23 4 views
1

C를 런타임 스크립팅 언어로 사용하려면 libtcc를 C에서 실행하려고합니다. 런타임 컴파일 된 코드는 외부 코드의 기능을 실행할 수 있어야합니다. 이것은 int를 전달할 때 잘 동작하지만, tcc 코드의 구조체를 gcc 코드로 전달할 때 이상한 일이 발생합니다.컴파일 된 gcc와 tcc 구조체의 호환성

최소한의 실행 예 :

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

가 왜 GCC는 컴파일 된 버전이 예상 0 인쇄되지 않습니다

#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(); 
} 

함께 실행? 구조체에 int 대신 long long만을 넣으면 작동합니다. 다른 데이터 유형과 무작위 항목이 출력됩니다.

처음에는 정렬이나 무언가 때문이라고 생각했지만 구조체에서 하나의 변수 만 사용하는 경우에도 발생했습니다.

내가 리눅스 3.16 x86_64에와 TCC 0.9.26

+0

아키텍처 및 운영 체제는 무엇입니까? Tinycc는 64 비트 x86-64 (a.k.a. amd64)보다 32 비트 x86 (a.k.a.ia32)에서 더 잘 작동합니다. –

+0

'Arch Linux x86_64'. 그러나 "더 잘 작동"한다는 것은 무엇을 의미합니까? 이것은 64 비트 버전의 버그입니까? – phiresky

+0

x86-64의 심각한 프로그램에서'tcc'를 사용할 수 없었습니다. tinycc는 64 비트에서 매우 버그가 있습니다. –

답변

3

을 사용하고이 문제가 C 및 C++ 매개 변수로 전체 "구조체 VEC 테스트"를 이해하는 방식을 중심 것으로 보인다. TCC에서는 포인터로 취급/가정합니다. C++에서는 포인터라는 것이 더 명확하게 명시 되어야만합니다. ("0을 얻었다"인쇄)가 예상대로 작동 공식 자식 저장소에서 TCC (libtcc)의 새 버전에서

got 5 
+1

무엇. C 표준은 struct가 작동하는 방법을 결정하지 않습니까? 그 코드 중 어느 것도 C++이 아닙니다. 감사! – phiresky

+2

@phiresky : 구조체는 값으로 전달됩니다. (컴파일러가 포인터를 사용하여 값을 전달하는 경우, 의미가 동일하다면 괜찮습니다.)'struct Vec test '매개 변수를 가진 함수가'Test'의 멤버를 수정하면 그 변화는 영향을 미치지 않습니다 호출자 - tcc 버전 0.9.25를 사용한 빠른 실험은 tcc가이 권한을 얻음을 나타냅니다. (나는이'TCCState '물건이 무엇인지 모른다.) –

+0

코드가 컴파일되지 않는다. '# include' 지시자에'<' and '>'구분자가 없습니다. –

1

:

#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(); 
} 

출력으로 나타납니다. gcc 4.9.3 및 tcc 0.9.26 (commit 00ba4b)에서 테스트되었습니다.