Re: dynamic cast problem
Re: dynamic cast problem
- Subject: Re: dynamic cast problem
- From: mark <email@hidden>
- Date: Sat, 26 May 2007 15:01:11 +1200
Title: Re: dynamic cast problem
Yesterday was a bad day for thinking for me.
Sorry if this was posted to carbon lists.
Here are the classes:
typedef class SelectedObject* SelectedObjectRef;
typedef
SelectedObjectRef SORef;
typedef
UInt32 SOOwnerID;
class
SelectedObject {
UInt16 refCt;
SelObjectClass objectClass;
OSType ready;
protected:
SOOwnerID ID; // need to
identify where the SO belongs. An SO in one view will
have
// different select flags to an
SO in another view
SelObjectType
objectType; // NYI
SelectionFlag selections;
static CFMutableSetRef soCache;
static void SOCacheSetProc(const
void* value,
void* ctx);
friend SORef
CheckSOCache(SelObjectClass objClass, UInt16 objType, SOOwnerID
iID, void*
data);
virtual OSStatus
CheckCache(SelObjectClass objClass, UInt16 dataType, void* data,
SORef *sor);
// the arrays are used to send
one select/deselect event when a whole lot
// of objects are selected/deselected. Sending 1000+
deselected events is not a good
//
idea
static CritRgn recentSelRgn;
static CFMutableSetRef
recentlySelected;
static CFMutableSetRef recentlyDeselected;
static OSStatus
PostMassSelOfOwner(SOOwnerID ID, Boolean selOrDesel, CFArrayRef
itsItems);
static OSStatus
PostMassSelectEvents(SOOwnerID whichID=0); // clears both arrays after sending
// dtEventKindObjectsSelected &
dtEventKindObjectsSelected
// If zero is passed, all are
sent (in seperate events for each ID)
OSStatus AddToSelected();
OSStatus
AddToDeselected();
void
SOCleanup();
public:
SelectedObject(SelObjectClass theObjClass, SOOwnerID ID);
SelectedObject(const SelectedObject &obj);
virtual
~SelectedObject();
UInt16 Retain();
UInt16
Release();
SelObjectClass
GetObjectClass();
virtual SelObjectType GetObjectType(); // NYI. Will always return zero.
SOOwnerID GetOwnerID();
virtual CFStringRef CopySOString();
virtual UInt64 GetSOData64(); //
these two will always return zero for the base class
virtual UInt32
GetSOData32(); // it is up to the
subclasses to return the correct values
SelectionFlag GetSelectFlags();
void DefineSelectFlag(SelectionFlag theFlags, Boolean
newValue);
void
ToggleSelectFlag(SelectionFlag theFlags);
Boolean IsSelectedOr(SelectionFlag
whichFlags); // returns true if any of
the passed flags are set
Boolean
IsSelectedAnd(SelectionFlag whichFlags);
// returns true if all of the passed flags are set
Boolean
AnySelection(); // returns true is any
flag is set
void
PostSelectedEvent(Boolean selected);
virtual Boolean
operator==(SelectedObject &obj);
virtual void DebugPrint(UInt32 v=0); // printf
virtual CFStringRef
DebugString(UInt32 v=0); // CFStringRef ->
CFShow
};
//-------------------------------------------------------------------------------------
class
SelectedFileObject:public SelectedObject {
OSType
sfoReady;
protected:
FSRef fsr;
virtual OSStatus CheckCache(SelObjectClass objClass, UInt16
dataType, void* data,
SORef *sor);
void
SFOCleanup();
public:
SelectedFileObject(const FSRef* fsrptr,
SOOwnerID ID);
SelectedFileObject(const
char* cpath, SOOwnerID
ID);
SelectedFileObject(CFURLRef url, SOOwnerID ID);
SelectedFileObject(const SelectedFileObject
&obj);
~SelectedFileObject();
CFStringRef
CopySOString();
UInt64 GetSOData64();
UInt32 GetSOData32();
FSRef* GetFSRefPtr();
virtual CFStringRef
CopyName();
Boolean operator==(SelectedFileObject &obj);
void
DebugPrint(UInt32 v=0); // printf
CFStringRef DebugString(UInt32 v=0); // CFStringRef -> CFShow
};
typedef class SelectedFileObject* SelectedFORef;
typedef
SelectedFORef SOFORef;
The plugin header uses this
typedef:
// parent class
typedef void* SelectedObjectRef;
typedef
SelectedObjectRef SORef; // shorter
name
// selected file objects
typedef void* SelectedFileObjectRef;
// subclass of SORef
typedef
SelectedFileObjectRef SOFORef;
Here is the casting routine: (it is
exported using extern "C")
SOFORef SOCastToSOF(SORef sor)
{
if
(sor==nil) {return nil;}
SelectedFORef
sof=nil;
printf("%s\n", typeid(*sor).name());
(1)
printf("%s\n", typeid(SelectedFileObject).name()); (2)
if
(typeid(*sor)==typeid(SelectedFileObject)) {
(3)
sof=(SOFORef)sor;
}
else {sof=nil;}
//
sof=dynamic_cast<SelectedFORef>(sor);
return
sof;
};
The routine is used by
plugins.
The plugins receive a SORef from the
parent application via another accessor routine and are
passed in an CFArray.
All the plugins ever receive are
pointers.
The passed SORef is not guaranteed to
be a SOFORef (much like a CFType is not guaranteed to be a CFString).
So they use this routine to convert it if possible.
(1) & (2) typeid statements print
'18SelectedFileObject' .
(3) always evaluates to false when the
routine is called by the plugin. But, if the owning app calls this
casting routine directly, it succeeds.
Someone from a C++ newsgroup suggested that
the vtable is getting 'lost' or mangled when passed through the
plugin.
Last bit of code. The CFArray
callbacks:
const void* SORefRetain(CFAllocatorRef alloc, const void* value) {
SORef
sor=(SORef)value;
sor->Retain();
return value;
};
void
SORefRelease(CFAllocatorRef alloc, const
void* value) {
SORef sor=(SORef)value;
sor->Release();
};
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden