Discussion:
VCL RTTI Info
(too old to reply)
Malcolm Smith
2008-07-04 18:10:49 UTC
Permalink
I have code which works in BCB5/6 but fails to compile in 2006/2007. I've
changed the code to what I thought was correct, but the data obtained is
invalid (access violations).

The function in question is this:

TMethod __fastcall Nmjfrtti::GetEventMethod( TObject* AObject, const
AnsiString& AEventName )
{
static TTypeKinds AEventType = Typinfo::TTypeKinds() << tkMethod;

Typinfo::PTypeInfo pSourceTypeInfo = reinterpret_cast<PTypeInfo>(
AObject->ClassInfo() );
const int APropCount = Typinfo::GetPropList( pSourceTypeInfo, AEventType,
NULL );

// now we need to populate a property list
TPropList SourcePropList;

#ifdef MJF_BCB10_UP
PPropList pSourcePropList = &SourcePropList;
Typinfo::GetPropList( pSourceTypeInfo, pSourcePropList );
#else
Typinfo::GetPropList( pSourceTypeInfo, AEventType, &(SourcePropList[0]) );
#endif

// make sure the event name actually exists
for( int i = 0; i < APropCount; ++i )
{
Typinfo::PPropInfo NextPropItem = SourcePropList[i];

// make sure we have valid property information
if( NULL == NextPropItem )
continue;

if( AnsiString( NextPropItem->Name ) == AEventName )
return Typinfo::GetMethodProp( AObject, SourcePropList[i] );
}

static TMethod NullMethod = { 0, 0 };
return NullMethod;
}

The code inside the #ifdef MJF_BCB10_UP must be incorrect, but I cannot see
why. At runtime I'm getting invalid addresses for 'NextPropItem', causing
AV's.

What's the correct code for 2006/2007 ?

Thanks in advance.
--
Malcolm Smith
MJ Freelancing
http://www.mjfreelancing.com

Associate Editor
C++Builder Developers Journal
http://www.bcbjournal.com
Clayton Arends
2008-07-04 18:57:02 UTC
Permalink
Post by Malcolm Smith
I have code which works in BCB5/6 but fails to compile in 2006/2007. I've
changed the code to what I thought was correct, but the data obtained is
invalid (access violations).
PPropList pSourcePropList = &SourcePropList;
Typinfo::GetPropList( pSourceTypeInfo, pSourcePropList );
Change the code to pass AEventType and the AV will go away:

Typinfo::GetPropList( pSourceTypeInfo, AEventType, &SourcePropList );

HTH,
Clayton
Malcolm Smith
2008-07-04 23:18:32 UTC
Permalink
Thanks for the extra set of eyes. I can't believe I didn't see that.
--
Malcolm Smith
MJ Freelancing
http://www.mjfreelancing.com

Associate Editor
C++Builder Developers Journal
http://www.bcbjournal.com
[snip]
Post by Clayton Arends
Typinfo::GetPropList( pSourceTypeInfo, AEventType, &SourcePropList );
HTH,
Clayton
Remy Lebeau (TeamB)
2008-07-06 06:43:25 UTC
Permalink
You are manually duplicating what GetMethodProp() already does internally.
Rather then looping through the RTTI items yourself, you should call
GetPropInfo() instead. It returns NULL if the specified property is not
found, and it is available in all versions without using compiler-specific
code. For example:

TMethod __fastcall Nmjfrtti::GetEventMethod( TObject* AObject, const
AnsiString& AEventName )
{
// make sure the event name actually exists
PPropInfo pPropInfo = GetPropInfo(AObject, AEventName, TTypeKinds()
<< tkMethod);
if( pPropInfo )
return GetMethodProp(AObject, pPropInfo);

static TMethod NullMethod = { 0, 0 };
return NullMethod;
}


Gambit
Malcolm Smith
2008-07-07 13:31:25 UTC
Permalink
Thanks Remy. Makes me wonder if other areas of my code are duplicating
what's already available. There's not a lot of info available on the RTTI
stuff, so I've sort of worked it out through trial and error.
--
Malcolm Smith
MJ Freelancing
http://www.mjfreelancing.com

Associate Editor
C++Builder Developers Journal
http://www.bcbjournal.com
Post by Remy Lebeau (TeamB)
You are manually duplicating what GetMethodProp() already does internally.
Rather then looping through the RTTI items yourself, you should call
GetPropInfo() instead. It returns NULL if the specified property is not
found, and it is available in all versions without using compiler-specific
code.
[snip]
Post by Remy Lebeau (TeamB)
Gambit
Remy Lebeau (TeamB)
2008-07-07 16:34:39 UTC
Permalink
Post by Malcolm Smith
Thanks Remy. Makes me wonder if other areas of my code
are duplicating what's already available. There's not a lot of
info available on the RTTI stuff, so I've sort of worked it out
through trial and error.
I highly recommend installing the VCL source code. Then you don't have to
guess anymore. You will know exactly what everything is doing.


Gambit
Duane Hebert
2008-07-08 14:08:12 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Malcolm Smith
Thanks Remy. Makes me wonder if other areas of my code
are duplicating what's already available. There's not a lot of
info available on the RTTI stuff, so I've sort of worked it out
through trial and error.
I highly recommend installing the VCL source code. Then you don't have
to guess anymore. You will know exactly what everything is doing.
So instead of demanding APIs to be documented, we all resort
to reading the implementation's code and try to guess it all
by ourselves.
Can't see me agree to this one.
Especially since it's in a different language. Not
everyone is well versed in Delphi.

But I don't think Remy is saying to not demand
that the API is documented. He seems to be offering
what seems to be the only valid advice given that the
APIs are NOT documented.
Hendrik Schober
2008-07-08 14:00:22 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Malcolm Smith
Thanks Remy. Makes me wonder if other areas of my code
are duplicating what's already available. There's not a lot of
info available on the RTTI stuff, so I've sort of worked it out
through trial and error.
I highly recommend installing the VCL source code. Then you don't have to
guess anymore. You will know exactly what everything is doing.
So instead of demanding APIs to be documented, we all resort
to reading the implementation's code and try to guess it all
by ourselves.
Can't see me agree to this one.
Post by Remy Lebeau (TeamB)
Gambit
Schobi
Ed Mulroy [TeamB]
2008-07-08 15:22:13 UTC
Permalink
Remy is not tying to be an apologist for the compiler documentation. His
goal is to get the man up and going. To that end he recommended what he has
found to be the surest way to resolve things.

. Ed
Post by Remy Lebeau (TeamB)
I highly recommend installing the VCL source code. Then you don't have
to guess anymore. You will know exactly what everything is doing.
So instead of demanding APIs to be documented, we all resort
to reading the implementation's code and try to guess it all
by ourselves.
Can't see me agree to this one.
Remy Lebeau (TeamB)
2008-07-08 17:32:15 UTC
Permalink
Post by Ed Mulroy [TeamB]
Remy is not tying to be an apologist for the compiler documentation.
His goal is to get the man up and going. To that end he recommended
what he has found to be the surest way to resolve things.
Exactly. Pascal really isn't that hard to understand. I spend almost every
day looking at the VCL source code for one thing or another. It has helped
tremendously in diagnosing problems, finding undocumented features to tasks
I need to perform, etc.


Gambit
Malcolm Smith
2008-07-21 11:22:28 UTC
Permalink
I have no problem with what Remy suggested. I do read the VCL source when I
know where to look, or I'm able to track it down.

In this particular case I obviously hadn't looked far enough.
--
Malcolm Smith
MJ Freelancing
http://www.mjfreelancing.com

Associate Editor
C++Builder Developers Journal
http://www.bcbjournal.com
Post by Remy Lebeau (TeamB)
Post by Ed Mulroy [TeamB]
Remy is not tying to be an apologist for the compiler documentation.
His goal is to get the man up and going. To that end he recommended
what he has found to be the surest way to resolve things.
Exactly. Pascal really isn't that hard to understand. I spend almost
every day looking at the VCL source code for one thing or another. It has
helped tremendously in diagnosing problems, finding undocumented features
to tasks I need to perform, etc.
Gambit
Malcolm Smith
2008-07-07 13:35:06 UTC
Permalink
Sorry....previous post went before I completed (and trimmed).

I found this code in my original function:

// This will also work:, but does not check if the event name exists
// return Typinfo::GetMethodProp( AObject, AEventName );

I was half way there ;-)
--
Malcolm Smith
MJ Freelancing
http://www.mjfreelancing.com

Associate Editor
C++Builder Developers Journal
http://www.bcbjournal.com
Post by Remy Lebeau (TeamB)
You are manually duplicating what GetMethodProp() already does
internally. Rather then looping through the RTTI items yourself, you
should call GetPropInfo() instead. It returns NULL if the specified
property is not found, and it is available in all versions without using
[snip
Gambit
Remy Lebeau (TeamB)
2008-07-07 16:36:07 UTC
Permalink
Post by Malcolm Smith
// This will also work:, but does not check if the event name exists
// return Typinfo::GetMethodProp( AObject, AEventName );
Yes, it does check. If the event name is not found, an EPropertyError
exception will be raised.


Gambit
Malcolm Smith
2008-07-07 13:33:04 UTC
Permalink
Remy,

would you believe I found this comment in my code:
--
Malcolm Smith
MJ Freelancing
http://www.mjfreelancing.com

Associate Editor
C++Builder Developers Journal
http://www.bcbjournal.com
Post by Remy Lebeau (TeamB)
You are manually duplicating what GetMethodProp() already does internally.
Rather then looping through the RTTI items yourself, you should call
GetPropInfo() instead. It returns NULL if the specified property is not
found, and it is available in all versions without using compiler-specific
TMethod __fastcall Nmjfrtti::GetEventMethod( TObject* AObject, const
AnsiString& AEventName )
{
// make sure the event name actually exists
PPropInfo pPropInfo = GetPropInfo(AObject, AEventName, TTypeKinds()
<< tkMethod);
if( pPropInfo )
return GetMethodProp(AObject, pPropInfo);
static TMethod NullMethod = { 0, 0 };
return NullMethod;
}
Gambit
Loading...