473,289 Members | 2,040 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,289 software developers and data experts.

Why won't this cast?

class SORef {...};
class SelectedFORef : public SORef {...};
SOFORef SOCastToSOF(SORef sor) {
SelectedFORef sof=nil;
sof=dynamic_cast<SelectedFORef>(sor);
return sof;
};

I am getting a problem where sor is not being cast to sof (becomes nil)
even though sor IS a SelectedFORef underneath. (I have a debug method
with details contents and type).

I am not a C++ expert.
What am I doing wrong?

Mark
May 25 '07 #1
18 3076
mark wrote:
class SORef {...};
class SelectedFORef : public SORef {...};
SOFORef SOCastToSOF(SORef sor) {
SelectedFORef sof=nil;
What's nil?

--
Ian Collins.
May 25 '07 #2
In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
mark wrote:
class SORef {...};
class SelectedFORef : public SORef {...};
SOFORef SOCastToSOF(SORef sor) {
SelectedFORef sof=nil;

What's nil?
nil == NULL.
Pascal version of NULL.
May 25 '07 #3
mark wrote:
In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
>mark wrote:
>>class SORef {...};
class SelectedFORef : public SORef {...};
SOFORef SOCastToSOF(SORef sor) {
SelectedFORef sof=nil;
What's nil?

nil == NULL.
Pascal version of NULL.
Then why hide it? You can't assign NULL to a class object, only a pointer.

You can't apply a dynamic_cast to a class object, only a reference of a
pointer to one.
--
Ian Collins.
May 25 '07 #4
In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
mark wrote:
In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
mark wrote:
class SORef {...};
class SelectedFORef : public SORef {...};
SOFORef SOCastToSOF(SORef sor) {
SelectedFORef sof=nil;
What's nil?
nil == NULL.
Pascal version of NULL.

Then why hide it? You can't assign NULL to a class object, only a pointer.

You can't apply a dynamic_cast to a class object, only a reference of a
pointer to one.
I am idiot.
Sorry.
Should be:

class SOObject {...};
typdef class SOObject * SORef;

class SelectedFileObject : public SOObject {...};
typedef class SelectedFileObject * SelectedFORef;

SOFORef SOCastToSOF(SORef sor) {
SelectedFORef sof=nil;
sof=dynamic_cast<SelectedFORef>(sor);
return sof;
};
May 25 '07 #5
mark wrote:
In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
>mark wrote:
>>In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:

mark wrote:
class SORef {...};
class SelectedFORef : public SORef {...};
>
>
SOFORef SOCastToSOF(SORef sor) {
SelectedFORef sof=nil;
What's nil?
nil == NULL.
Pascal version of NULL.
Then why hide it? You can't assign NULL to a class object, only a pointer.

You can't apply a dynamic_cast to a class object, only a reference of a
pointer to one.

I am idiot.
Sorry.
Should be:

class SOObject {...};
typdef class SOObject * SORef;

class SelectedFileObject : public SOObject {...};
typedef class SelectedFileObject * SelectedFORef;
It's seldom, if ever, a good idea to hide pointer types behind typedefs.
SOFORef SOCastToSOF(SORef sor) {
SelectedFORef sof=nil;
sof=dynamic_cast<SelectedFORef>(sor);
return sof;
};
Why not

SelectedFORef sof = dynamic_cast<SelectedFORef>(sor);
--
Ian Collins.
May 25 '07 #6
In article <5b**************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
mark wrote:
In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
mark wrote:
In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:

mark wrote:
class SORef {...};
class SelectedFORef : public SORef {...};
SOFORef SOCastToSOF(SORef sor) {
SelectedFORef sof=nil;
What's nil?
nil == NULL.
Pascal version of NULL.
Then why hide it? You can't assign NULL to a class object, only a pointer.

You can't apply a dynamic_cast to a class object, only a reference of a
pointer to one.
I am idiot.
Sorry.
Should be:

class SOObject {...};
typdef class SOObject * SORef;

class SelectedFileObject : public SOObject {...};
typedef class SelectedFileObject * SelectedFORef;
It's seldom, if ever, a good idea to hide pointer types behind typedefs.
Have to. The class pointer is available to plugins. And C++ doesn't like
plugins. So I typedef as a struct * for plugins and use accessor
routines.
>
SOFORef SOCastToSOF(SORef sor) {
This is an accessor routine for plugins.
The debugger shows it to still be a SelectedFORef class instance.
SelectedFORef sof=nil;
sof=dynamic_cast<SelectedFORef>(sor);
return sof;
};

Why not

SelectedFORef sof = dynamic_cast<SelectedFORef>(sor);
Did try that. Makes no difference.
Would the typedef actually screw things up?
May 25 '07 #7
mark wrote:
In article <5b**************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
>mark wrote:
>>In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:

mark wrote:
In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
>
>mark wrote:
>>class SORef {...};
>>class SelectedFORef : public SORef {...};
>>>
>>>
>>SOFORef SOCastToSOF(SORef sor) {
>> SelectedFORef sof=nil;
>What's nil?
nil == NULL.
Pascal version of NULL.
Then why hide it? You can't assign NULL to a class object, only a pointer.

You can't apply a dynamic_cast to a class object, only a reference of a
pointer to one.
I am idiot.
Sorry.
Should be:

class SOObject {...};
typdef class SOObject * SORef;

class SelectedFileObject : public SOObject {...};
typedef class SelectedFileObject * SelectedFORef;
It's seldom, if ever, a good idea to hide pointer types behind typedefs.

Have to. The class pointer is available to plugins. And C++ doesn't like
plugins. So I typedef as a struct * for plugins and use accessor
routines.
That's not a reason that makes any sense to me, (not saying it is wrong
though).
>>SOFORef SOCastToSOF(SORef sor) {

This is an accessor routine for plugins.
The debugger shows it to still be a SelectedFORef class instance.
>> SelectedFORef sof=nil;
sof=dynamic_cast<SelectedFORef>(sor);
return sof;
};
Why not

SelectedFORef sof = dynamic_cast<SelectedFORef>(sor);

Did try that. Makes no difference.
Would the typedef actually screw things up?
No.

Does class SOObject have at least one virtual function? You need at
least one virtual function for dynamic_cast to work.

When you say the cast is not working, what *exactly* do you mean? How
can you tell the cast is not working?

john

May 25 '07 #8
In article <GY**************@newsfe6-win.ntli.net>,
John Harrison <jo*************@hotmail.comwrote:
mark wrote:
In article <5b**************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
mark wrote:
In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:

mark wrote:
In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:

mark wrote:
>class SORef {...};
>class SelectedFORef : public SORef {...};
>>
>>
>SOFORef SOCastToSOF(SORef sor) {
> SelectedFORef sof=nil;
What's nil?
nil == NULL.
Pascal version of NULL.
Then why hide it? You can't assign NULL to a class object, only a
pointer.

You can't apply a dynamic_cast to a class object, only a reference of a
pointer to one.
I am idiot.
Sorry.
Should be:

class SOObject {...};
typdef class SOObject * SORef;

class SelectedFileObject : public SOObject {...};
typedef class SelectedFileObject * SelectedFORef;

It's seldom, if ever, a good idea to hide pointer types behind typedefs.
Have to. The class pointer is available to plugins. And C++ doesn't like
plugins. So I typedef as a struct * for plugins and use accessor
routines.

That's not a reason that makes any sense to me, (not saying it is wrong
though).
>SOFORef SOCastToSOF(SORef sor) {
This is an accessor routine for plugins.
The debugger shows it to still be a SelectedFORef class instance.
> SelectedFORef sof=nil;
sof=dynamic_cast<SelectedFORef>(sor);
return sof;
};
Why not

SelectedFORef sof = dynamic_cast<SelectedFORef>(sor);
Did try that. Makes no difference.
Would the typedef actually screw things up?

No.

Does class SOObject have at least one virtual function? You need at
least one virtual function for dynamic_cast to work.

When you say the cast is not working, what *exactly* do you mean? How
can you tell the cast is not working?
Mac OS X gdb debugger.
Inspecting sor with XCode/gdb shows it to be a SelectedFileObject
underneath. It's type is listed as such and not the base class SORef.
So the dynamic_cast should work (according to the C++ book I have,
virtual
john
Here's the full class definitions.

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;
May 25 '07 #9
mark wrote:
In article <GY**************@newsfe6-win.ntli.net>,
John Harrison <jo*************@hotmail.comwrote:
>mark wrote:
>>In article <5b**************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:

mark wrote:
In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
>
>mark wrote:
>>In article <5b*************@mid.individual.net>,
>> Ian Collins <ia******@hotmail.comwrote:
>>>
>>>mark wrote:
>>>>class SORef {...};
>>>>class SelectedFORef : public SORef {...};
>>>>>
>>>>>
>>>>SOFORef SOCastToSOF(SORef sor) {
>>>> SelectedFORef sof=nil;
>>>What's nil?
>>nil == NULL.
>>Pascal version of NULL.
>Then why hide it? You can't assign NULL to a class object, only a
>pointer.
>>
>You can't apply a dynamic_cast to a class object, only a reference of a
>pointer to one.
I am idiot.
Sorry.
Should be:
>
class SOObject {...};
typdef class SOObject * SORef;
>
class SelectedFileObject : public SOObject {...};
typedef class SelectedFileObject * SelectedFORef;
>
It's seldom, if ever, a good idea to hide pointer types behind typedefs.
Have to. The class pointer is available to plugins. And C++ doesn't like
plugins. So I typedef as a struct * for plugins and use accessor
routines.
That's not a reason that makes any sense to me, (not saying it is wrong
though).
>>>>SOFORef SOCastToSOF(SORef sor) {
This is an accessor routine for plugins.
The debugger shows it to still be a SelectedFORef class instance.

SelectedFORef sof=nil;
sof=dynamic_cast<SelectedFORef>(sor);
return sof;
};
Why not

SelectedFORef sof = dynamic_cast<SelectedFORef>(sor);
Did try that. Makes no difference.
Would the typedef actually screw things up?
No.

Does class SOObject have at least one virtual function? You need at
least one virtual function for dynamic_cast to work.

When you say the cast is not working, what *exactly* do you mean? How
can you tell the cast is not working?
Mac OS X gdb debugger.
Inspecting sor with XCode/gdb shows it to be a SelectedFileObject
underneath. It's type is listed as such and not the base class SORef.
So the dynamic_cast should work (according to the C++ book I have,
Right, so before you do the cast you definitely have a
SelectedFileObject, but if was after that I was wondering about. Does
NULL get assigned to sof, or something else? I'm asking how you know it
failed, not why you expect it to work. Just trying to eliminate all the
possibilities.

john
May 25 '07 #10
>>>>I am idiot.
>>>>Sorry.
Should be:
>
class SOObject {...};
typdef class SOObject * SORef;
>
class SelectedFileObject : public SOObject {...};
typedef class SelectedFileObject * SelectedFORef;
>
[snip]
>
Here's the full class definitions.

class SelectedObject {
UInt16 refCt;
[snip]
>
//-----------------------------------------------------------------------
--------------

class SelectedFileObject:public SelectedObject {
OSType sfoReady;
protected:
[snip]
>
typedef class SelectedFileObject* SelectedFORef;
typedef SelectedFORef SOFORef;
There's some confusion here

In your original code, the base class is called SOObject, in the class
definitions posted more recently, it's SelectedObject.

Could this be the problem, are you getting mixed up with your names?

john
May 25 '07 #11
In article <j3***************@newsfe4-win.ntli.net>,
John Harrison <jo*************@hotmail.comwrote:
mark wrote:
In article <GY**************@newsfe6-win.ntli.net>,
John Harrison <jo*************@hotmail.comwrote:
mark wrote:
In article <5b**************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:

mark wrote:
In article <5b*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:

mark wrote:
>In article <5b*************@mid.individual.net>,
> Ian Collins <ia******@hotmail.comwrote:
>>
>>mark wrote:
>>>class SORef {...};
>>>class SelectedFORef : public SORef {...};
>>>>
>>>>
>>>SOFORef SOCastToSOF(SORef sor) {
>>> SelectedFORef sof=nil;
>>What's nil?
>nil == NULL.
>Pascal version of NULL.
Then why hide it? You can't assign NULL to a class object, only a
pointer.
>
You can't apply a dynamic_cast to a class object, only a reference of a
pointer to one.
I am idiot.
Sorry.
Should be:

class SOObject {...};
typdef class SOObject * SORef;

class SelectedFileObject : public SOObject {...};
typedef class SelectedFileObject * SelectedFORef;

It's seldom, if ever, a good idea to hide pointer types behind typedefs.
Have to. The class pointer is available to plugins. And C++ doesn't like
plugins. So I typedef as a struct * for plugins and use accessor
routines.
That's not a reason that makes any sense to me, (not saying it is wrong
though).

SOFORef SOCastToSOF(SORef sor) {
This is an accessor routine for plugins.
The debugger shows it to still be a SelectedFORef class instance.

SelectedFORef sof=nil;
sof=dynamic_cast<SelectedFORef>(sor);
return sof;
};
Why not

SelectedFORef sof = dynamic_cast<SelectedFORef>(sor);
Did try that. Makes no difference.
Would the typedef actually screw things up?
No.

Does class SOObject have at least one virtual function? You need at
least one virtual function for dynamic_cast to work.

When you say the cast is not working, what *exactly* do you mean? How
can you tell the cast is not working?
Mac OS X gdb debugger.
Inspecting sor with XCode/gdb shows it to be a SelectedFileObject
underneath. It's type is listed as such and not the base class SORef.
So the dynamic_cast should work (according to the C++ book I have,

Right, so before you do the cast you definitely have a
SelectedFileObject, but if was after that I was wondering about. Does
NULL get assigned to sof, or something else? I'm asking how you know it
failed, not why you expect it to work. Just trying to eliminate all the
possibilities.

john
SelectedFORef sof=nil; <-- habit of setting vars to defaults.

sof=dynamic_cast<SelectedFORef>(sor); <-- sof is set to nil/NULL by
dynamic_cast

This routine is invoked by a plugin. sor is passed from APP -PLUGIN
-APP (above routine). The plugin just has a pointer to work with.
May 25 '07 #12
In article <w8****************@newsfe4-win.ntli.net>,
John Harrison <jo*************@hotmail.comwrote:
>>>I am idiot.
Sorry.
Should be:

class SOObject {...};
typdef class SOObject * SORef;

class SelectedFileObject : public SOObject {...};
typedef class SelectedFileObject * SelectedFORef;

[snip]

Here's the full class definitions.

class SelectedObject {
UInt16 refCt;

[snip]

//-----------------------------------------------------------------------
--------------

class SelectedFileObject:public SelectedObject {
OSType sfoReady;
protected:

[snip]

typedef class SelectedFileObject* SelectedFORef;
typedef SelectedFORef SOFORef;

There's some confusion here

In your original code, the base class is called SOObject, in the class
definitions posted more recently, it's SelectedObject.

Could this be the problem, are you getting mixed up with your names?

john
No.
The original posts were off the top of my head. Couldn't remember the
spellings.
I am not having a very intelligent day today.
The actual routine is this:

SOFORef SOCastToSOF(SORef sor) {
SelectedFORef sof=nil;
sof=dynamic_cast<SelectedFORef>(sor);
return sof;
};

Classes as given in previous post.

I changed the above to this:

OFORef SOCastToSOF(SORef sor) {
if (sor==nil) {return nil;}
SelectedFORef sof=nil;
printf("%s\n", typeid(*sor).name());
printf("%s\n", typeid(SelectedFileObject).name());
if (typeid(*sor)==typeid(SelectedFileObject)) {
sof=(SOFORef)sor;
}
else {sof=nil;}
// sof=dynamic_cast<SelectedFORef>(sor);
return sof;
};

The typeid.name() for '*sor' & 'SelectedFileObject' returned
'18SelectedFileObject'.
But the typeid(*sor)==typeid(SelectedFileObject) evaluates to false.
May 25 '07 #13
mark wrote:
>
SelectedFORef sof=nil; <-- habit of setting vars to defaults.
Pointless when it gets assigned on the next line...
sof=dynamic_cast<SelectedFORef>(sor); <-- sof is set to nil/NULL by
dynamic_cast

This routine is invoked by a plugin. sor is passed from APP -PLUGIN
-APP (above routine). The plugin just has a pointer to work with.
What is a plugin? The objects aren't being mangled by another language
by any chance?

--
Ian Collins.
May 25 '07 #14
In article <5b**************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
mark wrote:

SelectedFORef sof=nil; <-- habit of setting vars to defaults.
Pointless when it gets assigned on the next line...
sof=dynamic_cast<SelectedFORef>(sor); <-- sof is set to nil/NULL by
dynamic_cast

This routine is invoked by a plugin. sor is passed from APP -PLUGIN
-APP (above routine). The plugin just has a pointer to work with.

What is a plugin? The objects aren't being mangled by another language
by any chance?

They shouldn't as the plugin (loadable bundle/library) only recieves a
pointer.

The plugin uses this definition:
// parent class
typedef void* SelectedObjectRef;
typedef SelectedObjectRef SORef; // shorter name

// selected file objects
typedef void* SelectedFileObjectRef; // subclass of SORef
typedef SelectedFileObjectRef SOFORef;

The plugins are not necessarily written in C++.
The test plugin is written in C.

Also, some testing shows that if the object passes through the plugin,
the casting fails. Otherwise if the casting routine is called directly
by the owning app, it succeeds. This means there is some mangling going
on somewhere.
May 25 '07 #15
On May 25, 9:58 am, mark <trid...@ihug.co.nzwrote:

[...]
The typeid.name() for '*sor' & 'SelectedFileObject' returned
'18SelectedFileObject'.
But the typeid(*sor)==typeid(SelectedFileObject) evaluates to false.
I'm just guessing, since I don't know the environment in which
you are working. But you did mention something about the actual
objects being in a plugin. So this really have nothing to do
with C++ (which doesn't support plugins, yet), but are you
loading (under Unix) or building (under Windows) the plugin
correctly, so that its symbols and types are correctly exported
and found by the main program? Or is it a case where the
SelectedFileObject in the plugin is, as far as the program can
tell, totally unrelated to the class of the same name in the
main program.

Normally, a well designed plugin will be built and loaded in a
manner such that most of the symbols in it are NOT visible
outside it---the plugin interface may very well use a type
SelectedObject, which must be common to all plugins, but you
typically don't want conflicts just because two different
plugins decide to use the same name for the derived class---you
want it to be two different classes, as if they really had
different names. And of course, if this is the case,
typeid(...).name() will return the same value for the two
different classes.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 25 '07 #16
On May 25, 8:37 am, mark <trid...@ihug.co.nzwrote:
>
SOFORef SOCastToSOF(SORef sor) {
SelectedFORef sof=nil;
...
return sof;
};
Is SelectedFORef castable to SOFORef ?(you have not declared the later
type.)

May 25 '07 #17
mark wrote:
In article <5b**************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
>mark wrote:
>>SelectedFORef sof=nil; <-- habit of setting vars to defaults.
Pointless when it gets assigned on the next line...
>>sof=dynamic_cast<SelectedFORef>(sor); <-- sof is set to nil/NULL by
dynamic_cast

This routine is invoked by a plugin. sor is passed from APP -PLUGIN
-APP (above routine). The plugin just has a pointer to work with.
What is a plugin? The objects aren't being mangled by another language
by any chance?


They shouldn't as the plugin (loadable bundle/library) only recieves a
pointer.

The plugin uses this definition:
// parent class
typedef void* SelectedObjectRef;
typedef SelectedObjectRef SORef; // shorter name

// selected file objects
typedef void* SelectedFileObjectRef; // subclass of SORef
typedef SelectedFileObjectRef SOFORef;

The plugins are not necessarily written in C++.
The test plugin is written in C.

Also, some testing shows that if the object passes through the plugin,
the casting fails. Otherwise if the casting routine is called directly
by the owning app, it succeeds. This means there is some mangling going
on somewhere.
Does the same pointer come out as went in, it looks like the vtable may
be getting lost.

--
Ian Collins.
May 25 '07 #18
In article <11**********************@u30g2000hsc.googlegroups .com>,
terminator <fa***********@gmail.comwrote:
On May 25, 8:37 am, mark <trid...@ihug.co.nzwrote:

SOFORef SOCastToSOF(SORef sor) {
SelectedFORef sof=nil;
...
return sof;
};

Is SelectedFORef castable to SOFORef ?(you have not declared the later
type.)
Really bad day for thinking yesterday.

Here's everything:

Mac OS X. XCode 2.4.

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();
};
May 26 '07 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Aaron W. West | last post by:
Fun with CAST! (Optimized SQLServerCentral script posts) I found some interesting "tricks" to convert binary to hexadecimal and back, which allow doing 4 or 8 at a time. Test code first: --...
15
by: Gregg Woodcock | last post by:
My compiler (m68k-gcc) does not allow this (simplified example; not my real code) and I don't see why not: { char *arrayCharPtr1 = {"a", "ab", NULL}; char *arrayCharPtr2 = {"A", "AB", NULL};...
6
by: Adam Warner | last post by:
Hi all, When adding variable length arrays to my program I created the elements as type struct o *. This is because /most/ of the time the VLAs contains pointers to struct o objects (these...
17
by: Hazz | last post by:
In this sample code of ownerdraw drawmode, why does the '(ComboBox) sender' line of code need to be there in this event handler? Isn't cboFont passed via the managed heap, not the stack, into this...
1
by: Alpha | last post by:
I have a Window based application that shows up still running in the task manager when I close it. It reaches the "this.close" statement and then it stops at the "}" at the section of the...
5
by: Nick Flandry | last post by:
I'm running into an Invalid Cast Exception on an ASP.NET application that runs fine in my development environment (Win2K server running IIS 5) and a test environment (also Win2K server running IIS...
5
by: Frederick Gotham | last post by:
Before I begin, here's a list of assumptions for this particular example: (1) unsigned int has no padding bits, and therefore no invalid bit- patterns or trap representations. (2) All types have...
9
by: Ivan Jericevich | last post by:
In my code below at the line 'response' a blip sound is heard and the program exits the sub -- No MsgBox is displayed. What am I doing wrong? If nonNumberEntered = True Then msg = "Enter...
1
by: DerekBaker | last post by:
I had this code previously: void App::FillFontBox(HWND PrefsBox) { EnumFontFamilies(hdc,(LPCTSTR)NULL,(FONTENUMPROC)EnumFontNamesProc,(long)this);
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.