Random thoughts about AutoCAD, ObjectARX, and the meaning of life.
All Original Content Copyright 2006 - 2008 Owen Wengerd, All Rights Reserved
class AcGiFaceData: public AcRxObject
{
//[... deleted for brevity]
ACDB_PORT virtual AcDbObjectId* materials() const;
ACDB_PORT virtual AcGiMapper* mappers() const
virtual void setTransparency(const AcCmTransparency *transparency);
virtual AcCmTransparency* transparency() const
private:
AcGiImpFaceData *mpAcGiImpFaceData;
};
acrxEntryPoint.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AcGiFaceData::setTransparency(class AcCmTransparency const *)" (?setTransparency@AcGiFaceData@@UAEXPBVAcCmTransparency@@@Z)Following is an example that results in these errors:
acrxEntryPoint.obj : error LNK2001: unresolved external symbol "public: virtual class AcCmTransparency * __thiscall AcGiFaceData::transparency(void)const " (?transparency@AcGiFaceData@@UBEPAVAcCmTransparency@@XZ)
class AcGiFaceDataEx: public AcGiFaceData
{
public:
AcGiFaceDataEx() {}
~AcGiFaceDataEx() {}
} Test;
class AcGiFaceDataEx: public AcGiFaceDataThis will fix the linker errors, but there is no guarantee that it will work as intended. AutoCAD might access its internal transparency value directly without calling through the member functions, which means it would never "see" the transparency set through the replacement member functions. Furthermore, the addition of the new pointer member changes the size of the class, which causes AcGiFaceDataEx arrays to have a different memory footprint than AcGiFaceData arrays. Lastly, what if Autodesk fixes the problem in a future AutoCAD service pack?
{
AcCmTransparency* mpTransparency;
public:
AcGiFaceDataEx() : mpTransparency( NULL ) {}
~AcGiFaceDataEx() { delete mpTransparency; }
virtual void setTransparency(const AcCmTransparency *transparency)
{
delete mpTransparency;
mpTransparency = (transparency? new AcCmTransparency( *transparency ) : NULL);
}
virtual AcCmTransparency* transparency() const { return mpTransparency; }
} Test;
#pragma warning(push)
#pragma warning(disable: 4608)
template < typename Src, typename Dest >
Dest force_cast( Src src )
{
union _convertor { Dest d; Src s; _convertor() : d(0), s(0) {} } convertor;
convertor.s = src;
return convertor.d;
}
#pragma warning(pop)
static FARPROC* getAcGiFaceData_vtable()
{
static FARPROC* rfVTable = *(FARPROC**)&AcGiFaceData();
return (rfVTable? rfVTable : NULL);
}
void AcGiFaceData::setTransparency( const AcCmTransparency* transparency )
{
typedef void (AcGiFaceData::*F_setTransparency)( const AcCmTransparency* );
static F_setTransparency pfSetTransparency = force_cast< FARPROC, F_setTransparency >(GetProcAddress( GetModuleHandleA( "acdb18.dll"), "?setTransparency@AcGiFaceData@@UEAAXPEBVAcCmTransparency@@@Z" ));
if( !pfSetTransparency )
{
static FARPROC* rfVTable = getAcGiFaceData_vtable();
if( rfVTable )
pfSetTransparency = force_cast< FARPROC, F_setTransparency >( rfVTable[22] );
}
if( pfSetTransparency )
(this->*pfSetTransparency)( transparency );
}
AcCmTransparency* AcGiFaceData::transparency() const
{
typedef AcCmTransparency* (AcGiFaceData::*F_transparency)() const;
static F_transparency pfTransparency = force_cast< FARPROC, F_transparency >(GetProcAddress( GetModuleHandleA( "acdb18.dll"), "?transparency@AcGiFaceData@@UEBAPEAVAcCmTransparency@@XZ" ));
if( !pfTransparency )
{
static FARPROC* rfVTable = getAcGiFaceData_vtable();
if( rfVTable )
pfTransparency = force_cast< FARPROC, F_transparency >( rfVTable[23] );
}
if( pfTransparency )
return (this->*pfTransparency)();
return NULL;
}
I'm a starving artist specializing in the programming genre. I work in my home office, where I am the owner and sole proprietor of ManuSoft as well as the President and chief software artist of CADLock, Inc.