c에서 cpp 클래스 멤버 함수 호출에 관하여
글쓴이: cho's / 작성시간: 월, 2003/09/15 - 5:51오후
현재 c에서 cpp의 클래스 호출하려고 합니다.
형식은 다음과 같이 클래스 object를 가지고 와서 그 멤버 함수를 호출하려고 합니다. 세그멘트 에러가 나는데 이유를 잘 모르겠습니다.
어셈블 코드를 봐도 크게 틀린것 같지는 않은데요. 어떻게 해야 할까요?
그냥 멤버함수가 아닌형태로 하면 되긴 하지만 꼭 이렇게 해야만 될 이유가 있어서요.
t1.c
#include <stdio.h>
typedef struct _XX {
void (*ftn3)(void*);
int (*ftn4)(void*, int,int);
} XX;
void* get_ptr(void);
int main(int argc, char* argv[])
{
XX* p = (XX*)get_ptr();
p->ftn3(p);
p->ftn4(p, 10,11);
}
t2.cc
#include <stdio.h>
class X {
public:
int x;
int y;
static void ftn1(void);
static int ftn2(int,int);
};
void (X::*ftn1)(void);
void (X::*ftn2)(int, int);
void X::ftn1(void)
{
printf("X::ftn1.\n");
}
int X::ftn2(int x1,int y1)
{
int a,b;
int a1,b1;
int a2,b2;
printf("X::ftn2.(%d,%d)\n",x1,y1);
a=9;b=10;
a1=91;b1=101;
a2=92;b2=102;
//x=77;y=88;
}
X x0;
extern "C" void* get_ptr(void)
{
//int* p= (int*)&x0;
//printf("(%x,%x,%x,%x)\n",*p,*(p+1),*(p+2),*(p+3));
return (void*)(&x0);
t1.c를 어셈블 코드로 변환했을때 모습입니다. 이코드를 기준으로 살펴보고 있는데 클래스 오브젝을 받아서는 이상이 없고 이 받은것을 this처럼 넘기는데 제대로 된것 같거든요. 어셈 코드를 기준으로 자세히 설명해 주신다면 고맙겠습니다.
t1.s
main: pushl %ebp movl %esp, %ebp //stack frame을 ebp에 세팅 subl $8, %esp // 8byte를 확보한다는 얘긴가요? andl $-16, %esp // -16을 더하면 어떻게 되나요? movl $0, %eax // eax를 초기화하는 건가요? subl %eax, %esp call get_ptr movl %eax, -4(%ebp) // -4는 첫번째 지역번수 즉 class p를 가지고 온것 subl $12, %esp // 12byte를 어떻게 확보한다는 얘긴가요? movl -4(%ebp), %eax pushl -4(%ebp) movl (%eax), %eax call *%eax // 이 부분이 잘못된것 같습니다. 그냥 클래스를 부르는것 같습니다.어떻게 해야 할까요? addl $16, %esp subl $4, %esp movl -4(%ebp), %eax pushl $11 pushl $10 pushl -4(%ebp) movl 4(%eax), %eax call *%eax addl $16, %esp leave ret
상세하게 알고싶습니다. 솔직히 잘 이해가 안되거든요.
좋은 하루 되십시오.
Forums:


get_ptr 이 마치 생성자의 역할을 해야하는데, 그렇지 않은 코드이군
get_ptr 이 마치 생성자의 역할을 해야하는데, 그렇지 않은 코드이군요.
C++ member 함수를 호출할 때는, C++ 에서 (C아닌) wrapper 함수를 제공해주어야 정상적으로 호출할 수 있습니다.
심지어 위의 코드에서 X::ftn1, X::ftn2 함수는 static 이므로 this pointer가 넘어가지 않는 함수이군요.
어셈블 코드를 설명하는 방식이 아니어서 죄송합니다만. 위에 제시하신 class X를 C 코드에서 사용하려면, 다음과 같은 interface를 작성해주시는 것이 좋습니다. ftn1과 ftn2 를 static 으로 하지 않는 코드로 설명드리면..
t2.cc
class X { public: int x; int y; void ftn1(void); int ftn2(int,int); }; type void XX; extern "C" XX * X_init() { return (XX *) new X; } extern "C" void X_ftn1( XX * pthis ) { ((X*)pthis)->ftn1(); } extern "C" int X_ftn2( XX * pthis, int a, int b ) { return ((X*)pthis)->ftn2(a,b); } extern "C" void X_destroy( XX * pthis ) { delete pthis; }t1.c
int main(int argc, char* argv[]) { XX * p = X_init(); X_ftn1(p); X_ftn2(p,10,11); X_destroy( p ); }... 컴파일 안하고 올리는거라 오류가 있다면 답글 주세요. 메모리 할당 오류 등은 생략하였습니다.
---
http://coolengineer.com
댓글 달기