클래스 객체를 구조체 객체 C / C ++로 캐스팅
두 개의 프로젝트가 C에 있고 다른 하나가 C ++에 있고 C ++의 클래스 개체를 C의 구조 개체로 캐스팅하려고합니다. 예를 들어 다음과 같이 myStru로 캐스팅하려는 myClass의 개체가 있습니다.
내 C ++ 프로젝트에는이 클래스가 있습니다.
class myClass{
myClass();
~myClass();
char *data;
int var;
}
내 C 프로젝트에는 다음 구조가 있습니다.
struct myStru {
char *data;
int var;
};
typedef struct myStru myStru;
이제 내 C ++ 프로젝트에서 myClass
다음 에서 개체를 만듭니다 .
myClass *classObj = new myClass();
classObj->data = new char[10];
classObj->var = 99;
내 C 프로젝트에서 나는 classObj
void 포인터로 받고 다음과 같이 캐스팅하려고합니다.
myStru *struObj = (myStru*)malloc(sizeof(struct myStru));
struObj = (myStru*) classObj;
printf(" struObj->var %d \n", struObj->var); // this print 99
나중에 C ++ 프로젝트에서 수행합니다.
delete []classObj->data; // I know smart pointers can be used here but this is not my point in this question now
delete classObj;
내가 여기서하는 일이 맞나요? 즉, 주조 classObj
에 struObj
그런 식으로?
전체 예제는 여기에서 찾을 수 있습니다 (@Borgleader에게 감사드립니다) http://coliru.stacked-crooked.com/a/05543b944ee23f2f
편집 :이 기사에서 내 질문에 대한 좋은 대답을 찾았습니다 (C에서 C ++ 클래스 액세스 참조). https://www.oracle.com/technical-resources/articles/it-infrastructure/mixing-c-and-cplusplus.html
답변
100 % 확신 할 수는 없습니다. C ++이고 절대 그럴 수 없기 때문입니다.하지만 이것은 정의되지 않은 동작이라고 생각합니다.
다른 구조체의 멤버에 대한 포인터를 통해 구조체의 멤버에 액세스 할 수 없습니다. 이 규칙의 주목할만한 예외는 공용체의 구성원 인 두 구조체의 공통 초기 시퀀스에 액세스하는 것입니다.
대신 구조체에서 실제로 클래스를 상속 한 경우 작동 할 수 있습니다.
또는 다른 예외는 memcpy
이러한 구조체 AFAIR간에 안전하게 할 수 있다는 것 입니다.
이 질문은 상호 운용성에 관한 것이며 C 및 C ++ 컴파일러의 구현 정의 측면에 의존하기 때문에 확실한 답을 얻지 못할 것입니다. struct
와는 class
C ++ 측면에서 레이아웃 호환 유형입니다. 하나의 a class
와 하나의 a 를 선언 하는 struct
것은 문제가 아니며 두 구성원 모두 모든 구성원에 대해 동일한 구성원 액세스 권한을 갖기 때문에 (서로 다르지만) 호환 가능 하다는 것이 매우 분명합니다 (적어도 C ++ 14 이상에서는 내가 믿습니다) .
표준이 제공하는 최선의 방법은 다음과 같습니다.
참고 : 표준 레이아웃 클래스는 다른 프로그래밍 언어로 작성된 코드와 통신하는 데 유용합니다. 레이아웃은 12.2에 지정되어 있습니다. — 엔드 노트
의도 (표준 레이아웃 레이아웃 호환 둘 다) 등의 클래스 간의 상호 동작 할 수 있다는 것이다. 두 가지 모드에서 동일한 컴파일러를 사용하는 경우 이것이 작동하지 않으면 '실망'합니다. 하지만 그것이 '실망'할 수있는 최선의 방법입니다. 문서를 확인하십시오.
전반적인 전략에서 자원 관리에 대해 조금 궁금합니다. C ++에서 소멸자를 선언 했지만 class
괜찮습니다 virtual
!)하지만 struct
C 코드에 '소멸자 유사'함수가있어 문제를 일으킬 수있는 객체를 파괴하는 '소멸자 유사'함수가있는 경우 C 측에 복사 합니다. C ++ 개체를 비트 단위로 복제했습니다.
C free(s->data)
가 사용했던 C ++로 구성된 객체의 복사본을 호출 new
하면 정의되지 않은 동작이 발생합니다. 이는 malloc()
호환성을 위해 C ++ 측에서 사용 하는 것을 보증하는 예외적 인 경우 일 수 있습니다 .
따라서 괜찮을 수 있지만 C와 C ++ 간의 상호 운용성 기능에 의존하고 있으며 두 표준은 가능한 한 멀리 데려가지만 정의에 따라 구현 정의 기능을 사용하고 있습니다.
참고로 우리는 표준이 기꺼이 작동한다는 것을 알고 있으며 아마도 그렇게 될 것입니다. 행운을 빕니다!