|
Ah, but it is portable - see Inside the C++ Object Model (S. Lippman), pages 121-124. Static functions are managled internally into non-class functions. "Taking the address of a static memmber function always yields the value of its location in memory, that is, its address. Because the static function is without a this pointer, the type of its address is not a pointer to a class member function but the type of a nonmember pointer to function." Sadly, the ARM doesn't give more than a trivial explanation of static data and functions, other than they have "external linkage". What reference were you using for the undefiend functionality?
In any case, you can work around the private/protected problem like this:
void bogus(void *ptr) { ((Fred*)ptr)->publicBogus(); }
class Fred
{
public:
void publicBogus() { ; /* do the real work here */ }
};
|
|
|
|
|
You're confusing portable (as in conforming to the ANSI/ISO standard) with "it works" based on a common implementation. Inside the C++ Object model was written long before the standard (1996). IIRC he even states that what he writes is based on common implementations.
|
|
|
|
|
Thank you all for your input. My original unease was well justified. The code is a turkey. I will use your suggestions and chuck in a static member function and work my requirements around it.
It's certainly been an eye-opener!
|
|
|
|
|
Just as a final note, it looks like this union trick has been seen before.
Stroustrup addresses this form of type conversion using unions in appendix C, section 8.3, and trounces it as non-portable, for pretty much the reasons Todd gave.
It seems that unions are poor cousins in the world of C++. Originally, I think the point was to allow C coders to save space. C++ adds some stuff that make it hard to fully assimilate unions into the language - e.g. classes with non-default ctors or dtors or copy ctors cant be used in a union (which dtor would you call?). Aside from that restriction, I get the impression that C++ has to weaken type checking in order to accomodate unions, which would explain why the union got around the parameter type checking for the calls to CreateThread and _beginthread, where no cast could. The tagged union construct (e.g. VARIANT) seems to have its place, but maybe unions should be considered harmful in C++.
Ok. I'll go away now. Happy coding!
|
|
|
|
|
I see you've already recieved answers to your questions, but I thought I would just cover the basic reasons why this is the case.
In C++, member functions do not have the same function signature as a non-member function except (in most cases) when the member function is static. I say in most cases because this is a compiler dependant implementation issue and is undefined in the standard, however the logical way to implement it is the way most compilers do (including VC).
C++ member functions pass a hidden first parameter called "this". When you call an object, it's translated to a different syntax so that the real call looks as so:
object.func(); is really called this way:
class::func(class* const this); So in reality, all member functions are non-member functions that are namespace qualified and pass a hidden first parameter that allows the function to know where it's instance data is. Something else most people don't realize is that a function that's declared const, such as:
void dosomething(void) const; is called this way:
void class::dosomething(class const * const this); This means that if you manage to hoodwink the compiler into compiling a non-member function pointer into a member function pointer, you're going to corrupt the stack. It also explains why when you pass the object instance as the parameter to function, it instead allowed it to be used for "this"; a lucky hack that is bound to break eventually.
So, in closing. Member function pointers and non-member function pointers are not the same type, even if they look like it.
|
|
|
|
|
Yes. I found all this out the hard way by going into the VS disassembler and looking at the calls and the stack.
There are two issues here anyway: the fake union cast and external calls into member functions. After all the good advice from everyone here and checking up in Bjarne Stroustrup's (whew, I hope I spelt it right) book I think I will stick to the straight and narrow from now on. It's safer.
|
|
|
|
|
this macro comes with pure win32, not mfc
Please HELP
|
|
|
|
|
Go to the following address: J.M. Newcomer homepage. Or, even better, buy the definite Win32 SDK/GUI guide: "Win32 Programming" (J.M. Newcomer & Brent Rector). It is on Amazon at Win32 Programming. I'm reading this book every day and still isn't enough...
However, it isn't a very good idea to mix MFC with pure Win32 techniques (unless you are sure what you are doing). Keep the standard message routing as 'standard' as possible; if you're on MFC, use MFC; if you're on Win32 SDK, use SDK. The MFC does a lot of things for you, but you have to play almost always by his rules. Complete customization is, indeed, offered by SDK, but there you have to build your own message maps (it's not so hard, even in pure Win32 C programming). Read the book (also Jeffrey Richter's "Advanced Win32 Programming" contains useful samples, although this book is OS oriented, not especially GUI) and apply the advices.
|
|
|
|
|
Why OnSize() in window starts 3 three times?
|
|
|
|
|
Well, the reason is quite simple. Your window changes size three times.
When the window is created, it's initial size is 0,0,0,0. That's the first size change. The first thing the OS does is resize the window to the size you specify, or the default. Let's pretend that's 100,100,100,100. That's the second size change. Third, you are probably sizing the window yourself, causing the third size change.
|
|
|
|
|
How i can change or delete the (default)title which appear when i open some view in my mdi project?
where is the place for it?
thx.
|
|
|
|
|
SetWindowText("MY Title"); in the view class.
Christian
The content of this post is not necessarily the opinion of my yadda yadda yadda.
To understand recursion, we must first understand recursion.
|
|
|
|
|
How can I create an exe file when my program is running but I do not have any other files which my program will need. Its a bit like self-extracting exe files but not the same principle. I did see a program one day: you supply a normal txt file, it gives you an exe file with that txt file appended into it. Another is a trainer which creates an exe file after you gave it a few details but it doesn't use any other external files. What is more amazing is that when the product exe is run, it creates a dll.
How can I create this type of program?
Please reply.
|
|
|
|
|
I think some progs can contain binaries that were originally loaded as resouces - there's a trick or two to identifying their location and size, but it can be done. Search for installers - I think WDJ had an article on this a while back.
|
|
|
|
|
Hello all,
I'm using Nullsoft's SuperPimp installer (open source installer!) for a project that I created. It has some patch files for some source that was compiled using visual c++ 6. Can anyone tell me how to automatically install the patch files? They come with .txt extensions. What extension should they use and where should I put them? Thanks in advance.
--Tale
|
|
|
|
|
Hello all,
I'm using Nullsoft's SuperPimp installer (open source installer!) for a project that I created. It has some patch files for some source that was compiled using visual c++ 6. Can anyone tell me how to automatically install the patch files? They come with .txt extensions. What extension should they use and where should I put them? Thanks in advance.
--Tale
|
|
|
|
|
Hi, ive writtena little utility which i plan to release as freeware.
part of this utility will transfer some data between two computers connected over tcp/ip.
Its' a MFC / dialog box interface.
the problem is this:
if i DONT limit the data to about 1kb at a time, then the data does NOT get transferred correctly over the internet - so to transfer 1 meg, i gota break it up into 1000 parts and send them. which i think must make the operation pretty slow.
is this NORMAL? and what is a workaround if one exists?
i havnt testes the exaact limit of the size i can send, but i know its under 5kb.
any help would be much appreciated
thanks
John McGrath
tails_naf@yahoo.com
|
|
|
|
|
This is 'sort of kind of' normal.
You can 'send' up to the size of your sockets send buffer, but to a large extent, the actual data chunk that goes down the wire is determined by the max transmission unit (MTU). This is normally around 563 ? bytes for the internet. This is determined by a legacy of routers that couldn't handle larger packet sizes, and normal for a win9x system. If you exceed this limit with a send, the socket will fragment the packets. This causes some overhead processing to occur.
I've suspected in the past that this fragmentation can lead to problems when shutting down sockets etc, but this may just be my paranoia. Still, if I were to venture some advice, I'd say send in 512 (room for IP and TCP header left) byte chunks - I don't know if there is any more efficiency (other than conscripting some sort of proxy to do the sending) to be had.
|
|
|
|
|
> the problem is this: if i DONT limit the data to about 1kb at a time,
> then the data does NOT get transferred correctly over the internet
How does it not get transferred correctly? TCP/IP will let you transfer > 1KB in a single call, but there is no guarantee that the corresponding receive call will get all of the data in one shot.
For example, you can send a 4KB chunk in a single send(...) call, but the receive(...) on the other side may return with only 2KB copied into the buffer. This is normal. You need to break up your data into packets, and then keep track of the packets as they are received so that you can coalesce them if they get fragmented.
One way to do this is to send packets that are always of a fixed size. This is a bit ineffecient for the last packet, if it contains data that is less that that size, but it allows you to know when you have a full packet on the other side. (You need to embed the size of the data within the packet.)
Other way is to design a packet that contains a header that includes a signature, and the side of the packet (including the header). That way, the receive side can keep calling receive(...) until it has a complete packet, and then process the packet.
-=- James.
|
|
|
|
|
sndPlaySound( "sounds//alienlaser.wav", SND_ASYNC);
I use that code to play sound, works great but.. if i play the sound and i play another sound
nearly the same time, one of the sounds doesnt play right.. Hope you know what i mean, i was wondoring if i was doing somthing wrong in the code.
Thank you.
|
|
|
|
|
I don't know, but I'd suspect you'd do better with Direct Sound for multiple sounds at once.
Christian
The content of this post is not necessarily the opinion of my yadda yadda yadda.
To understand recursion, we must first understand recursion.
|
|
|
|
|
i play the sound and i play another sound nearly the same time
The sndPlaySound(..) will not do that simply because it won't return (Free the Sound Device) until the previous sound is fully played till end. The next sound is only played once the Sound Device is free from playing the one before.
Instead, use MCI stuff or better yet as Christian mentioned, use DirectSound stuff.
Good Luck!
|
|
|
|
|
In developing an MDI application written strictly in C (no MFC or WFC), I've discovered something very disturbing. If you add a resource file (.rc) to your application, you have to be careful of what you name your resources. For example, I tried naming the Cascade item in my Window menu ID_WINDOW_CASCADE. When I compile, I get an error saying that ID_WINDOW_CASCADE is already defined. Looking through my files, I discover that my .rc file is including 'afxres.h', an MFC file!!! What gives? If I comment out the include file, I get a bunch of new errors when I compile.
Are there any issues with including this file? It doesn't look like the file will make my app MFC reliant, but I want to make sure. Anybody have any thoughts?
Thanks in advance.
Jamie Nordmeyer
Portland, Oregon, USA
|
|
|
|
|
Looks like "TN035: Using Multiple Resource Files and Header Files with Visual C++" might be of some help. Afxres.h is including winres.h - a subset of windows.h. If you not referencing afxres.rc in the .rc file, maybe you can get away with replacing afxres with winres. Some of the include stuff is wrapped in #ifdefs, so it looks like VC is just trying to be as flexible as possible with its resource files. Maybe you can just pare the whole thing down if you want to be a purist - depends what the resource editor does to things. Interesting.
|
|
|
|
|
How best to encode ascii files in c++
1. Create as binary?
2. Exclusive or (^) --- how do I do this ??
Thanks
Gerry.
|
|
|
|