How do I store a pointer to a C++ class in a C struct?
I'm working with an API where the basic unit of storage is a C struct (MaxMSP). I'd like to use C++. I've attempted to store a pointer to my class in a void* but deleting it (in C++) causes a crash
extern "C" void* MyClass_New(){
MyClass* temp = new MyClass();
return (void*)temp;
}
extern "C" void MyClass_Delete(void* myclass){
delete (MyClass*)myclass; //<--- this line crashes.
}
I'm aware this is ugly and dangerous but I don't see another way to do this. do you?
I expected a void* would adequately keep track of a C++ class but calling delete after casting said void* causes a crash.
/////// Here's my minimal reproducible.
.c:
int main(int argc, const char * argv[]) {
void* temp;
temp= MyClassTranslator_New(4);
MyClassTranslator_Kill(temp);
return 0;
}
.hpp
#ifndef m2ot_base_hpp
#define m2ot_base_hpp
#if defined __cplusplus
extern "C" class MyClassTranslator
{
private :
long num;
public:
MyClassTranslator(const long num);
~MyClassTranslator(){;};
MyClassTranslator( const MyClassTranslator &obj);
long getNum(void){return this->num;};
};
extern "C" void* MyClassTranslator_New(const long num);
extern "C" void MyClassTranslator_Kill(void* thisc);
#endif
#endif /* m2ot_base_hpp */
.cpp
MyClassTranslator::MyClassTranslator( const MyClassTranslator &that){
this->num=that.num;
}
extern "C" void* MyClassTranslator_New(const long num)
{
MyClassTranslator* temp= new MyClassTranslator(num);
return static_cast<void*> (temp);
}
extern "C" void MyClassTranslator_Kill(void* thisc){
delete static_cast<MyClassTranslator*>(thisc);
}
MyClassTranslator::MyClassTranslator(const long num){
this->num=num;
}
Can I store pointers to C++ classes in C?
Yes.
but deleting it (in C++) causes a crash
There are a few possibilities:
MyClass_Delete
that didn't originate from MyClass_New
. MyClass_Delete
more than once. Regarding style:
The cast in MyClass_New
is redundant.
I recommend not using C style cast in C++. You can use static_cast
to convert from void*
.
You could use a wrapper such as:
struct MyClass_handle {
void* ptr;
};
struct MyClass_handle MyClass_New();
void MyClass_Delete(struct MyClass_handle myclass);
The use of typed handle makes it easier to catch incorrect usage.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.