I start learning VC++/MFC. then I created a "HelloWord" program,
I got two App.h/.cpp AppDlg.h/.cpp basic files by created a basic Dialog project.
The first problem: I can't find the program entry. there is no main.cpp in the project.
Then I tried to find the relationship between App and AppDlg, met the second problem: base on the file name, looks like AppDlg should be a customized MFC Dialog component, and the App supposes to be the main event thread. But I got below in both .cpp files. it included each other. I thought AppDlg should be the part of App.
#include "App.h"
#include "AppDlg.h"
these two problem makes me confused about the structure of the project.
Why MFC code looks so different? For what purpose do like this?
The reason you don't have a "main" function (quoted because it's not actually called main(a)) is because the code has already been written for you. This is quite common in frameworks, where a certain amount of set-up is done before the code you're responsible for actually starts running.
In fact, this is often the case even for situations where you do create a main(), since there's usually start-up code that's responsible for doing things like turning the arguments into argc/argc objects to hand over to your main code (if you ever see an object file like crt0.o or ucrt.lib, that's probably the C run-time start-up code).
In the early days of Windows, the code you wrote had a WinMain() function(a) which was called by the start-up code in lieu of main(), and it was typically responsible for registering window classes, creating and starting message pumps, and all sorts of other stuff which is usually identical in every application. So, by moving that work to a framework of some description, it greatly reduces the amount of code you need to write.
In terms of how this works, think of what would happen if the stuff you linked to contained the following:
int main(int argc, char *argv[]) {
return bob(argc, argv);
}
Then your code would not actually need a main() function at all. It would need a bob() function of course and that's very similar to the situation you've discovered: Microsoft has written their own "main" function in the MFC framework which sets up things so that MFC will work.
Admittedly, my bob-based framework doesn't provide as much benefit as MFC but it's only meant to be an example of how it can be done :-)
In terms of what goes into each file created by each project type, this link may help. For example, the two files you mentioned are covered by:
<projname>.h : the main include file for the program or DLL. It contains all global symbols and #include directives for other header files. It derives the C<projname>App class from CWinApp and declares an InitInstance member function. For a control, the C<projname>App class is derived from COleControlModule.
<projname>dlg.cpp and <projname>dlg.h : created if you choose a dialog-based application. The files derive and implement the dialog class, named C<projname>Dlg, and include skeleton member functions to initialise a dialog and perform dialog data exchange (DDX). Your About dialog class is also placed in these files instead of in <projname>.cpp.
Note that there's nothing in those descriptions about a message pump (for example). That's because all the heavy lifting for that is included in the base classes for the things that are created.
(a) The reason why it *wasn't main() can be found in this article on The Old New Thing - it was basically to ensure no clash between what the language supplied and what Windows needed.
Related
In a Qt project we generally find a project.pro file, the main.cpp and several header, source and *.ui files, containing all the resources to breathe life and function into the application/project.
If there is more to it than "press the button to show 'Hello, world!'", there might be directories for storing data and configuration files, etc.
My question is (in spite of the fact that an exact answer depends on the specific situation):
What is the general role of the main.cpp in a Qt project (Qt Widgets Application)?
To make clear what I mean:
Is the main.cpp's only purpose to kick off the application?
If not, what are typical tasks to be performed by the main.cpp?
Speaking of config files - consider the application has a main form which has (and maybe other classes/dialogs instantiated by the main form as well) to know about some configuration data retrieved from a file. Would the initialization happen in the main.cpp or in the MainForm. In short: "Setting things up..." should be placed where (in the light of the current question)?
Whatever you feel like saying...
(Note: A complete answer should incorporate #thokra's comment, which is to say that main.cpp is a filename and the appearance of the program entry point in a file with that name is only convention. But it's a fairly well-adhered to convention in Qt programs and C++ in general to try and put the program's entry point in a file with that name.)
One category would be registration of global hooks and settings. Think about things like qInstallMessageHandler, or QTextCodec::setCodecForCStrings.
Initialization of any non-Qt libraries that your app wants to take for granted would be another area.
If your program has a main window object that's only created and destroyed one time, it might seem equally suitable to put the "run once" code in its constructor/destructor. But ask yourself exactly what is it about your app that only lets it have one main window. Why wouldn't it be able to have two in the same process? Even if that's not part of the requirement today, it can suggest an architectural boundary.
I'll mention from personal experience that if you try making a class derived from QApplication, and then put your global run-once-code in the constructor and destructor of that derived class, that is trickier than it sounds (especially if you spawn threads and make widgets in that constructor). So I don't think in most scenarios you should derive from QApplication. I stuck with it because I was making an application framework...but avoid that and your run-once code goes in the main.cpp.
"1. Is the main.cpp's only purpose to kick off the application?"
As from the c++ [standards definition]1 the 1st section says:
3.6 Start and termination [basic.start]
3.6.1 Main function [basic.start.main]
1 A program shall contain a global function called main, which is the designated start of the program. It
is implementation-defined whether a program in a freestanding environment is required to define a main
function.
[ Note: In a freestanding environment, start-up and termination is implementation-defined; startup
contains the execution of constructors for objects of namespace scope with static storage duration;
termination contains the execution of destructors for objects with static storage duration. —end note ]
A qt application is still using C++, thus this constraint needs to be satisfied for any executable application.
So presumably: Yes, the main()'s only purpose is to kick off the application.
MainForm and main() aren't really strongly related, other than your configuration will generate a main() function instantiating and calling it. You can also have Qt projects, that don't have any MainForm instance at all (e.g. a just command line app).
I am working on a C++ project in Xcode, and one of my .cpp files instantiates some variables. Another .cpp file in the application uses these variables to instantiate another object and needs them to be instantiated to not throw a null-pointer exception. My solution so far was simply to drag-drop (XCode simplicity) the first file over the second one in the build-phase order. It works fine now, but I have a feeling that it is not the optimal solution, and that there is something fundamentally wrong with my code if I need to organise the compile order manually for the application to run properly.
Should I never instantiate something outside of functions, or what is the golden rule? Thanks.
EDIT: An example as requested.
The problem lies in a Observer/Event system.
In a source-file I do this:
Trigger* mainMenu_init = new Trigger(std::vector<Event*> {
// Event(s):
event_gameInit,
}, [](Event* e) {
// Action(s):
std::cout << "Hello World" << std::endl;
});
In the trigger's constructor the Event is asked to add is as an observer:
for(Event* event : events)
event->addObserver(this);
BUT, the events are just external pointers, so if they are not initialised (which they are in another source-file) this initialisation will fail. So what I found was that if I do not organise the compilation-phase myself, random triggers will not work while other will, depending on if they are built before or after the Event.cpp file.
I assume you are talking about non-trivial initialization of global variables (or of static variables), such as (at the top level of a file):
MyObject *myPtrObject = new MyObject(42, "blah");
MyObject myOtherObject;
("trivial" initialization is, roughly speaking, when there is no constructor involved and everything just involves constants; so if you initialize a pointer to zero, it will be zero before any code is actually invoked)
The order of initialization between different source files is NOT GUARANTEED in C++. It happens to depend on the order of the files with Apple's current system, but THAT MIGHT CHANGE.
So yes, there is something fundamentally wrong.
Golden Rules
IMPORTANT: In the initialization of a global object, don't use any other global objects from different source files.
Don't overuse global variables. They have numerous disadvantages from a software design point of view.
Keep initialization of global objects simple. That will make it easier to stick to the first rule.
Not knowing anything about your program, it's of course hard to give more concrete design advice.
I have some global variables (classes) that as I understand have created before main() call. I need some technique to add data to a List of something either global or as member of that class from any part of my code and it have to be filled before Linker. To use it inside globally created classes. Is it possible? I did not find any similar solution or even question, so any help will be appreciated.
Detailed example:
I've have singleton class which has a variable that was filled in the constructor. All other classes use data from the class at run time someone early someone later. Singleton class is created at the begin of main function. I am using singleton in different projects, data that it has mostly universal for all projects and modules except special flag which should show requirement for this module. If singleton throw exception program exits and we know it at the first steps of execution because singleton creates at first lines of the main. So singleton has a lot of universal data for all projects but I need to add flags to point for singleton which data is required for each module. I have created template for main so for each project I have the same main with just simple define PROJECT_NAME later I add .cpp to the project and they have to register which data is required and which not.
This explanation not looks like perfect, if it is not understandable don't hesitate to say it I will organize it more deliberately.
Edited:
I'm still looking for solution in the Internet, and found constexpr it looks like what I need, but at this moment it is not supported by all compilers, is there some workaround ?
First step is to not use global variables, but instead use static variables within a global function. The first time the function is called the variable will be initialized and then have the function return a reference to the varaible.
my_class& instnace() {
static my_class i;
return i;
}
A list example:
std::list<my_class>& global_list() {
static std::list<my_class> m; return m;
}
static int x = []()->int{ global_list().push_back(my_class); return 0;}();
If you want to accomplish what you want from different modules , one of the way is to have things done is some sort of callback function when your dll is loaded.
One windows it is DLLMain.
An optional entry point into a dynamic-link library (DLL). When the
system starts or terminates a process or thread, it calls the
entry-point function for each loaded DLL using the first thread of the
process. The system also calls the entry-point function for a DLL when
it is loaded or unloaded using the LoadLibrary and FreeLibrary
functions.
On other platforms with gcc you can get by the [attribute constructor]
constructor The constructor attribute causes the function to be called
automatically before execution enters main (). Similarly, the
destructor attribute causes the function to be called automatically
after main () has completed or exit () has been called. Functions with
these attributes are useful for initializing data that will be used
implicitly during the execution of the program. These attributes are
not currently implemented for Objective-C.
Warning
It is very easy to shoot yourself in the foot with this method. At least on windows that are lot of things you cannot do in the dll entry point. Please read your compiler/os documentation to see what the limitations are.
From what I can tell you can kick off all the action in a constructor when you create a global object. So do you really need a main() function in C++ or is it just legacy?
I can understand that it could be considered bad practice to do so. I'm just asking out of curiosity.
If you want to run your program on a hosted C++ implementation, you need a main function. That's just how things are defined. You can leave it empty if you want of course. On the technical side of things, the linker wants to resolve the main symbol that's used in the runtime library (which has no clue of your special intentions to omit it - it just still emits a call to it). If the Standard specified that main is optional, then of course implementations could come up with solutions, but that would need to happen in a parallel universe.
If you go with the "Execution starts in the constructor of my global object", beware that you set yourself up to many problems related to the order of constructions of namespace scope objects defined in different translation units (So what is the entry point? The answer is: You will have multiple entry points, and what entry point is executed first is unspecified!). In C++03 you aren't even guaranteed that cout is properly constructed (in C++0x you have a guarantee that it is, before any code tries to use it, as long as there is a preceeding include of <iostream>).
You don't have those problems and don't need to work around them (wich can be very tricky) if you properly start executing things in ::main.
As mentioned in the comments, there are however several systems that hide main from the user by having him tell the name of a class which is instantiated within main. This works similar to the following example
class MyApp {
public:
MyApp(std::vector<std::string> const& argv);
int run() {
/* code comes here */
return 0;
};
};
IMPLEMENT_APP(MyApp);
To the user of this system, it's completely hidden that there is a main function, but that macro would actually define such a main function as follows
#define IMPLEMENT_APP(AppClass) \
int main(int argc, char **argv) { \
AppClass m(std::vector<std::string>(argv, argv + argc)); \
return m.run(); \
}
This doesn't have the problem of unspecified order of construction mentioned above. The benefit of them is that they work with different forms of higher level entry points. For example, Windows GUI programs start up in a WinMain function - IMPLEMENT_APP could then define such a function instead on that platform.
Yes! You can do away with main.
Disclaimer: You asked if it were possible, not if it should be done. This is a totally un-supported, bad idea. I've done this myself, for reasons that I won't get into, but I am not recommending it. My purpose wasn't getting rid of main, but it can do that as well.
The basic steps are as follows:
Find crt0.c in your compiler's CRT source directory.
Add crt0.c to your project (a copy, not the original).
Find and remove the call to main from crt0.c.
Getting it to compile and link can be difficult; How difficult depends on which compiler and which compiler version.
Added
I just did it with Visual Studio 2008, so here are the exact steps you have to take to get it to work with that compiler.
Create a new C++ Win32 Console Application (click next and check Empty Project).
Add new item.. C++ File, but name it crt0.c (not .cpp).
Copy contents of C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src\crt0.c and paste into crt0.c.
Find mainret = _tmain(__argc, _targv, _tenviron); and comment it out.
Right-click on crt0.c and select Properties.
Set C/C++ -> General -> Additional Include Directories = "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src".
Set C/C++ -> Preprocessor -> Preprocessor Definitions = _CRTBLD.
Click OK.
Right-click on the project name and select Properties.
Set C/C++ -> Code Generation -> Runtime Library = Multi-threaded Debug (/MTd) (*).
Click OK.
Add new item.. C++ File, name it whatever (app.cpp for this example).
Paste the code below into app.cpp and run it.
(*) You can't use the runtime DLL, you have to statically link to the runtime library.
#include <iostream>
class App
{
public: App()
{
std::cout << "Hello, World! I have no main!" << std::endl;
}
};
static App theApp;
Added
I removed the superflous exit call and the blurb about lifetime as I think we're all capable of understanding the consequences of removing main.
Ultra Necro
I just came across this answer and read both it and John Dibling's objections below. It was apparent that I didn't explain what the above procedure does and why that does indeed remove main from the program entirely.
John asserts that "there is always a main" in the CRT. Those words are not strictly correct, but the spirit of the statement is. Main is not a function provided by the CRT, you must add it yourself. The call to that function is in the CRT provided entry point function.
The entry point of every C/C++ program is a function in a module named 'crt0'. I'm not sure if this is a convention or part of the language specification, but every C/C++ compiler I've come across (which is a lot) uses it. This function basically does three things:
Initialize the CRT
Call main
Tear down
In the example above, the call is _tmain but that is some macro magic to allow for the various forms that 'main' can have, some of which are VS specific in this case.
What the above procedure does is it removes the module 'crt0' from the CRT and replaces it with a new one. This is why you can't use the Runtime DLL, there is already a function in that DLL with the same entry point name as the one we are adding (2). When you statically link, the CRT is a collection of .lib files, and the linker allows you to override .lib modules entirely. In this case a module with only one function.
Our new program contains the stock CRT, minus its CRT0 module, but with a CRT0 module of our own creation. In there we remove the call to main. So there is no main anywhere!
(2) You might think you could use the runtime DLL by renaming the entry point function in your crt0.c file, and changing the entry point in the linker settings. However, the compiler is unaware of the entry point change and the DLL contains an external reference to a 'main' function which you're not providing, so it would not compile.
Generally speaking, an application needs an entry point, and main is that entry point. The fact that initialization of globals might happen before main is pretty much irrelevant. If you're writing a console or GUI app you have to have a main for it to link, and it's only good practice to have that routine be responsible for the main execution of the app rather than use other features for bizarre unintended purposes.
Well, from the perspective of the C++ standard, yes, it's still required. But I suspect your question is of a different nature than that.
I think doing it the way you're thinking about would cause too many problems though.
For example, in many environments the return value from main is given as the status result from running the program as a whole. And that would be really hard to replicate from a constructor. Some bit of code could still call exit of course, but that seems like using a goto and would skip destruction of anything on the stack. You could try to fix things up by having a special exception you threw instead in order to generate an exit code other than 0.
But then you still run into the problem of the order of execution of global constructors not being defined. That means that in any particular constructor for a global object you won't be able to make any assumptions about whether or not any other global object yet exists.
You could try to solve the constructor order problem by just saying each constructor gets its own thread, and if you want to access any other global objects you have to wait on a condition variable until they say they're constructed. That's just asking for deadlocks though, and those deadlocks would be really hard to debug. You'd also have the issue of which thread exiting with the special 'return value from the program' exception would constitute the real return value of the program as a whole.
I think those two issues are killers if you want to get rid of main.
And I can't think of a language that doesn't have some basic equivalent to main. In Java, for example, there is an externally supplied class name who's main static function is called. In Python, there's the __main__ module. In perl there's the script you specify on the command line.
If you have more than one global object being constructed, there is no guarantee as to which constructor will run first.
If you are building static or dynamic library code then you don't need to define main yourself, but you will still wind up running in some program that has it.
If you are coding for windows, do not do this.
Running your app entirely from within the constructor of a global object may work just fine for quite awhile, but sooner or later you will make a call to the wrong function and end up with a program that terminates without warning.
Global object constructors run during the startup of the C runtime.
The C runtime startup code runs during the DLLMain of the C runtime DLL
During DLLMain, you are holding the DLL loader lock.
Tring to load another DLL while already holding the DLL loader lock results in a swift death for your process.
Compiling your entire app into a single executable won't save you - many Win32 calls have the potential to quietly load system DLLs.
There are implementations where global objects are not possible, or where non-trivial constructors are not possible for such objects (especially in the mobile and embedded realms).
Sooooo I'm writing a script interpreter. And basically, I want some classes and functions stored in a DLL, but I want the DLL to look for functions within the programs that are linking to it, like,
program dll
----------------------------------------------------
send code to dll-----> parse code
|
v
code contains a function,
that isn't contained in the DLL
|
list of functions in <------/
program
|
v
corresponding function,
user-defined in the
program--process the
passed argument here
|
\--------------> return value sent back
to the parsing function
I was wondering basically, how do I compile a DLL with gcc? Well, I'm using a windows port of gcc. Once I compile a .dll containing my classes and functions, how do I link to it with my program? How do I use the classes and functions in the DLL? Can the DLL call functions from the program linking to it? If I make a class { ... } object; in the DLL, then when the DLL is loaded by the program, will object be available to the program? Thanks in advance, I really need to know how to work with DLLs in C++ before I can continue with this project.
"Can you add more detail as to why you want the DLL to call functions in the main program?"
I thought the diagram sort of explained it... the program using the DLL passes a piece of code to the DLL, which parses the code, and if function calls are found in said code then corresponding functions within the DLL are called... for example, if I passed "a = sqrt(100)" then the DLL parser function would find the function call to sqrt(), and within the DLL would be a corresponding sqrt() function which would calculate the square root of the argument passed to it, and then it would take the return value from that function and put it into variable a... just like any other program, but if a corresponding handler for the sqrt() function isn't found within the DLL (there would be a list of natively supported functions) then it would call a similar function which would reside within the program using the DLL to see if there are any user-defined functions by that name.
So, say you loaded the DLL into the program giving your program the ability to interpret scripts of this particular language, the program could call the DLLs to process single lines of code or hand it filenames of scripts to process... but if you want to add a command into the script which suits the purpose of your program, you could say set a boolean value in the DLL telling it that you are adding functions to its language and then create a function in your code which would list the functions you are adding (the DLL would call it with the name of the function it wants, if that function is a user-defined one contained within your code, the function would call the corresponding function with the argument passed to it by the DLL, the return the return value of the user-defined function back to the DLL, and if it didn't exist, it would return an error code or NULL or something). I'm starting to see that I'll have to find another way around this to make the function calls go one way only
This link explains how to do it in a basic way.
In a big picture view, when you make a dll, you are making a library which is loaded at runtime. It contains a number of symbols which are exported. These symbols are typically references to methods or functions, plus compiler/linker goo.
When you normally build a static library, there is a minimum of goo and the linker pulls in the code it needs and repackages it for you in your executable.
In a dll, you actually get two end products (three really- just wait): a dll and a stub library. The stub is a static library that looks exactly like your regular static library, except that instead of executing your code, each stub is typically a jump instruction to a common routine. The common routine loads your dll, gets the address of the routine that you want to call, then patches up the original jump instruction to go there so when you call it again, you end up in your dll.
The third end product is usually a header file that tells you all about the data types in your library.
So your steps are: create your headers and code, build a dll, build a stub library from the headers/code/some list of exported functions. End code will link to the stub library which will load up the dll and fix up the jump table.
Compiler/linker goo includes things like making sure the runtime libraries are where they're needed, making sure that static constructors are executed, making sure that static destructors are registered for later execution, etc, etc, etc.
Now as to your main problem: how do I write extensible code in a dll? There are a number of possible ways - a typical way is to define a pure abstract class (aka interface) that defines a behavior and either pass that in to a processing routine or to create a routine for registering interfaces to do work, then the processing routine asks the registrar for an object to handle a piece of work for it.
On the detail of what you plan to solve, perhaps you should look at an extendible parser like lua instead of building your own.
To your more specific focus.
A DLL is (typically?) meant to be complete in and of itself, or explicitly know what other libraries to use to complete itself.
What I mean by that is, you cannot have a method implicitly provided by the calling application to complete the DLLs functionality.
You could however make part of your API the provision of methods from a calling app, thus making the DLL fully contained and the passing of knowledge explicit.
How do I use the classes and functions in the DLL?
Include the headers in your code, when the module (exe or another dll) is linked the dlls are checked for completness.
Can the DLL call functions from the program linking to it?
Yes, but it has to be told about them at run time.
If I make a class { ... } object; in the DLL, then when the DLL is loaded by the program, will object be available to the program?
Yes it will be available, however there are some restrictions you need to be aware about. Such as in the area of memory management it is important to either:
Link all modules sharing memory with the same memory management dll (typically c runtime)
Ensure that the memory is allocated and dealloccated only in the same module.
allocate on the stack
Examples!
Here is a basic idea of passing functions to the dll, however in your case may not be most helpfull as you need to know up front what other functions you want provided.
// parser.h
struct functions {
void *fred (int );
};
parse( string, functions );
// program.cpp
parse( "a = sqrt(); fred(a);", functions );
What you need is a way of registering functions(and their details with the dll.)
The bigger problem here is the details bit. But skipping over that you might do something like wxWidgets does with class registration. When method_fred is contructed by your app it will call the constructor and register with the dll through usage off methodInfo. Parser can lookup methodInfo for methods available.
// parser.h
class method_base { };
class methodInfo {
static void register(factory);
static map<string,factory> m_methods;
}
// program.cpp
class method_fred : public method_base {
static method* factory(string args);
static methodInfo _methoinfo;
}
methodInfo method_fred::_methoinfo("fred",method_fred::factory);
This sounds like a job for data structures.
Create a struct containing your keywords and the function associated with each one.
struct keyword {
const char *keyword;
int (*f)(int arg);
};
struct keyword keywords[max_keywords] = {
"db_connect", &db_connect,
}
Then write a function in your DLL that you pass the address of this array to:
plugin_register(keywords);
Then inside the DLL it can do:
keywords[0].f = &plugin_db_connect;
With this method, the code to handle script keywords remains in the main program while the DLL manipulates the data structures to get its own functions called.
Taking it to C++, make the struct a class instead that contains a std::vector or std::map or whatever of keywords and some functions to manipulate them.
Winrawr, before you go on, read this first:
Any improvements on the GCC/Windows DLLs/C++ STL front?
Basically, you may run into problems when passing STL strings around your DLLs, and you may also have trouble with exceptions flying across DLL boundaries, although it's not something I have experienced (yet).
You could always load the dll at runtime with load library