Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old January 12th, 2006, 07:45 AM
Rennie deGraaf
Guest
 
Posts: n/a
Default Reading a method pointer from a stream

Let's say that I want to read a method pointer in from a stream. (I'm
not saying that this is a good design idea, or that I actually have a
reason to do this.) If I wanted to read in a function pointer, I could
do something like this:

#include <iostream>

int*(*readFunction())(int, int*)
{
unsigned long x;
std::cin >> x;
return reinterpret_cast<int*(*)(int, int*)>(x);
}

int main()
{
std::cout << reinterpret_cast<unsigned long>(readFunction()) <<
std::endl;
}

I'm assuming here that my input is valid and that an unsigned long is at
least as large as a pointer, but it works on my system.

However, if I try to do something similar to read in a pointer to a
method in a class A, like this:

#include <iostream>

struct A {
int* foo(int, int*)
{
return NULL;
}
};

int* (A::*readMethod())(int, int*)
{
unsigned long x;
std::cin >> x;
return reinterpret_cast<int*(A::*)(int, int*)>(x);
}

int main()
{
std::cout << reinterpret_cast<unsigned long>(readMethod()) <<
std::endl;
}

my compiler (g++ 4.0.2) spits out these errors:

test3.cpp: In function ‘int* (A::* readMethod())(int, int*)’:
test3.cpp:14: error: invalid cast from type ‘long unsigned int’ to
type ‘int* (A::*)(int, int*)’
test3.cpp: In function ‘int main()’:
test3.cpp:20: error: invalid cast from type ‘int* (A::*)(int, int*)’
to type ‘long unsigned int’

I can't simply change ReadMethod() to read in an int*(A::*)(int, int*)
without a cast, since there's no >> operator for that type, and I can't
think of a way to define one without a conversion from some integer type
at some point.

sizeof tells me that an int*(A::*)(int, int*) is 8 bytes on my system,
the same size as an unsigned long long (an g++ extension), but changing
"unsigned long" to "unsigned long long" in the above code doesn't change
the results.

Any suggestions on how to do this?

Thanks,
Rennie deGraaf
  #2  
Old January 12th, 2006, 10:05 AM
Jim Langston
Guest
 
Posts: n/a
Default Re: Reading a method pointer from a stream

"Rennie deGraaf" <ca.ucalgary.cpsc@degraaf> wrote in message
news:_Gnxf.86208$tl.63562@pd7tw3no...[color=blue]
> Let's say that I want to read a method pointer in from a stream. (I'm
> not saying that this is a good design idea, or that I actually have a
> reason to do this.) If I wanted to read in a function pointer, I could
> do something like this:
>
> #include <iostream>
>
> int*(*readFunction())(int, int*)
> {
> unsigned long x;
> std::cin >> x;
> return reinterpret_cast<int*(*)(int, int*)>(x);
> }
>
> int main()
> {
> std::cout << reinterpret_cast<unsigned long>(readFunction()) <<
> std::endl;
> }
>
> I'm assuming here that my input is valid and that an unsigned long is at
> least as large as a pointer, but it works on my system.
>
> However, if I try to do something similar to read in a pointer to a
> method in a class A, like this:
>
> #include <iostream>
>
> struct A {
> int* foo(int, int*)
> {
> return NULL;
> }
> };
>
> int* (A::*readMethod())(int, int*)
> {
> unsigned long x;
> std::cin >> x;
> return reinterpret_cast<int*(A::*)(int, int*)>(x);
> }
>
> int main()
> {
> std::cout << reinterpret_cast<unsigned long>(readMethod()) <<
> std::endl;
> }
>
> my compiler (g++ 4.0.2) spits out these errors:
>
> test3.cpp: In function ‘int* (A::* readMethod())(int, int*)’:
> test3.cpp:14: error: invalid cast from type ‘long unsigned int’ to
> type ‘int* (A::*)(int, int*)’
> test3.cpp: In function ‘int main()’:
> test3.cpp:20: error: invalid cast from type ‘int* (A::*)(int, int*)’
> to type ‘long unsigned int’
>
> I can't simply change ReadMethod() to read in an int*(A::*)(int, int*)
> without a cast, since there's no >> operator for that type, and I can't
> think of a way to define one without a conversion from some integer type
> at some point.
>
> sizeof tells me that an int*(A::*)(int, int*) is 8 bytes on my system,
> the same size as an unsigned long long (an g++ extension), but changing
> "unsigned long" to "unsigned long long" in the above code doesn't change
> the results.
>
> Any suggestions on how to do this?
>
> Thanks,
> Rennie deGraaf[/color]

Consider a union. A union is usually a cheap way to do a conversion that C
or C++ doesn't want to do. You'll have to play around with the proper sytax
to get the function pointer to work, but I'll presume that your function
pointer is working correctly.

union
{
int* (A::*readMethod())(int, int*);
unsigned unsigned long Pointer;
} ConvertPoint;

std::cin >> ConvertPoint.Pointer;

at this point readMethod would contain the pointer.

Of course none of this is really safe or in any conceivable way portable.
It should work the other way to, assign readPointer and the Pointer var
holds the int ... umm.. version? of it.


  #3  
Old January 12th, 2006, 06:45 PM
Rennie deGraaf
Guest
 
Posts: n/a
Default Re: Reading a method pointer from a stream

Jim Langston wrote:[color=blue]
> "Rennie deGraaf" <ca.ucalgary.cpsc@degraaf> wrote in message
> news:_Gnxf.86208$tl.63562@pd7tw3no...
>[color=green]
>>Let's say that I want to read a method pointer in from a stream. (I'm
>>not saying that this is a good design idea, or that I actually have a
>>reason to do this.) If I wanted to read in a function pointer, I could
>>do something like this:
>>
>> #include <iostream>
>>
>> int*(*readFunction())(int, int*)
>> {
>> unsigned long x;
>> std::cin >> x;
>> return reinterpret_cast<int*(*)(int, int*)>(x);
>> }
>>
>> int main()
>> {
>> std::cout << reinterpret_cast<unsigned long>(readFunction()) <<
>>std::endl;
>> }
>>
>>I'm assuming here that my input is valid and that an unsigned long is at
>>least as large as a pointer, but it works on my system.
>>
>>However, if I try to do something similar to read in a pointer to a
>>method in a class A, like this:
>>
>> #include <iostream>
>>
>> struct A {
>> int* foo(int, int*)
>> {
>> return NULL;
>> }
>> };
>>
>> int* (A::*readMethod())(int, int*)
>> {
>> unsigned long x;
>> std::cin >> x;
>> return reinterpret_cast<int*(A::*)(int, int*)>(x);
>> }
>>
>> int main()
>> {
>> std::cout << reinterpret_cast<unsigned long>(readMethod()) <<
>>std::endl;
>> }
>>
>>my compiler (g++ 4.0.2) spits out these errors:
>>
>> test3.cpp: In function ‘int* (A::* readMethod())(int, int*)’:
>> test3.cpp:14: error: invalid cast from type ‘long unsigned int’ to
>>type ‘int* (A::*)(int, int*)’
>> test3.cpp: In function ‘int main()’:
>> test3.cpp:20: error: invalid cast from type ‘int* (A::*)(int, int*)’
>>to type ‘long unsigned int’
>>
>>I can't simply change ReadMethod() to read in an int*(A::*)(int, int*)
>>without a cast, since there's no >> operator for that type, and I can't
>>think of a way to define one without a conversion from some integer type
>>at some point.
>>
>>sizeof tells me that an int*(A::*)(int, int*) is 8 bytes on my system,
>>the same size as an unsigned long long (an g++ extension), but changing
>>"unsigned long" to "unsigned long long" in the above code doesn't change
>>the results.
>>
>>Any suggestions on how to do this?
>>
>>Thanks,
>>Rennie deGraaf[/color]
>
>
> Consider a union. A union is usually a cheap way to do a conversion that C
> or C++ doesn't want to do. You'll have to play around with the proper sytax
> to get the function pointer to work, but I'll presume that your function
> pointer is working correctly.
>
> union
> {
> int* (A::*readMethod())(int, int*);
> unsigned unsigned long Pointer;
> } ConvertPoint;
>
> std::cin >> ConvertPoint.Pointer;
>
> at this point readMethod would contain the pointer.
>
> Of course none of this is really safe or in any conceivable way portable.
> It should work the other way to, assign readPointer and the Pointer var
> holds the int ... umm.. version? of it.[/color]

Thanks, that's a good idea.

I was messing around with a framework that I wrote that can serialize
and deserialize objects of any type, trying to see how many types of
types I could handle with it. I can make it work for POD types,
classes, template classes, data pointers, function pointers, and now,
method pointers. It won't work with arrays or references. Am I missing
anything?

Rennie deGraaf
  #4  
Old January 13th, 2006, 03:35 AM
Jim Langston
Guest
 
Posts: n/a
Default Re: Reading a method pointer from a stream


"Rennie deGraaf" <ca.ucalgary.cpsc@degraaf> wrote in message
news:xexxf.201737$2k.196441@pd7tw1no...[color=blue]
> Jim Langston wrote:[color=green]
>> "Rennie deGraaf" <ca.ucalgary.cpsc@degraaf> wrote in message
>> news:_Gnxf.86208$tl.63562@pd7tw3no...
>>[color=darkred]
>>>Let's say that I want to read a method pointer in from a stream. (I'm
>>>not saying that this is a good design idea, or that I actually have a
>>>reason to do this.) If I wanted to read in a function pointer, I could
>>>do something like this:
>>>
>>> #include <iostream>
>>>
>>> int*(*readFunction())(int, int*)
>>> {
>>> unsigned long x;
>>> std::cin >> x;
>>> return reinterpret_cast<int*(*)(int, int*)>(x);
>>> }
>>>
>>> int main()
>>> {
>>> std::cout << reinterpret_cast<unsigned long>(readFunction()) <<
>>>std::endl;
>>> }
>>>
>>>I'm assuming here that my input is valid and that an unsigned long is at
>>>least as large as a pointer, but it works on my system.
>>>
>>>However, if I try to do something similar to read in a pointer to a
>>>method in a class A, like this:
>>>
>>> #include <iostream>
>>>
>>> struct A {
>>> int* foo(int, int*)
>>> {
>>> return NULL;
>>> }
>>> };
>>>
>>> int* (A::*readMethod())(int, int*)
>>> {
>>> unsigned long x;
>>> std::cin >> x;
>>> return reinterpret_cast<int*(A::*)(int, int*)>(x);
>>> }
>>>
>>> int main()
>>> {
>>> std::cout << reinterpret_cast<unsigned long>(readMethod()) <<
>>>std::endl;
>>> }
>>>
>>>my compiler (g++ 4.0.2) spits out these errors:
>>>
>>> test3.cpp: In function ‘int* (A::* readMethod())(int, int*)’:
>>> test3.cpp:14: error: invalid cast from type ‘long unsigned int’ to
>>>type ‘int* (A::*)(int, int*)’
>>> test3.cpp: In function ‘int main()’:
>>> test3.cpp:20: error: invalid cast from type ‘int* (A::*)(int, int*)’
>>>to type ‘long unsigned int’
>>>
>>>I can't simply change ReadMethod() to read in an int*(A::*)(int, int*)
>>>without a cast, since there's no >> operator for that type, and I can't
>>>think of a way to define one without a conversion from some integer type
>>>at some point.
>>>
>>>sizeof tells me that an int*(A::*)(int, int*) is 8 bytes on my system,
>>>the same size as an unsigned long long (an g++ extension), but changing
>>>"unsigned long" to "unsigned long long" in the above code doesn't change
>>>the results.
>>>
>>>Any suggestions on how to do this?
>>>
>>>Thanks,
>>>Rennie deGraaf[/color]
>>
>>
>> Consider a union. A union is usually a cheap way to do a conversion that
>> C
>> or C++ doesn't want to do. You'll have to play around with the proper
>> sytax
>> to get the function pointer to work, but I'll presume that your function
>> pointer is working correctly.
>>
>> union
>> {
>> int* (A::*readMethod())(int, int*);
>> unsigned unsigned long Pointer;
>> } ConvertPoint;
>>
>> std::cin >> ConvertPoint.Pointer;
>>
>> at this point readMethod would contain the pointer.
>>
>> Of course none of this is really safe or in any conceivable way portable.
>> It should work the other way to, assign readPointer and the Pointer var
>> holds the int ... umm.. version? of it.[/color]
>
> Thanks, that's a good idea.
>
> I was messing around with a framework that I wrote that can serialize
> and deserialize objects of any type, trying to see how many types of
> types I could handle with it. I can make it work for POD types,
> classes, template classes, data pointers, function pointers, and now,
> method pointers. It won't work with arrays or references. Am I missing
> anything?
>
> Rennie deGraaf[/color]

bool and bitfields? // should be fairly easy

enums? // should be fairly easy

How about std::string? That might prove intesting since the actual data is
not stored in the string object itself but memory the object points to. I
think you'd have that problem with all stl containers, but std::string is
definately necessary. You might as well do vector to as they'll be close to
identical. Although populating them would probably be different.



 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles