|
When you compile a .CPP or .C file an .OBJ file (object file) is produced. There are also .LIB files (library files) which can be regarded as a collection of .OBJ files. These files cannot be loaded or executed by the OS. When you link the input is .OBJ and .LIB files and the output is an executable (generally a file with the .EXE or .DLL extensions). These files can be loaded and executed by the OS. What I'm describing is how things work in Windows, but the same principles hold for other systems.
Steve
|
|
|
|
|
thanks you for your answer...
But what is the content of this .Obj fle?....how we compile them?
-----------------------------
I am a beginner
|
|
|
|
|
hrishiS wrote: how we compile them?
You don't. They are the result of the compilation. The linker uses one or more of them to create the final EXE or DLL.
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
Imaging the following program (in a imaginairy programming language):
Local int x,y
x=5
y=sin(x)
Now assume the function Sin() is not specified in this program, but in a library. When the program is compiled the compiler knows how to compile the first 2 statements (it can replace these statements to machine code that does functionally the same). This is written to the OBJ-file. The compiler can not compile the last line because this is an external defined function. So the compiler writes in the obj-file the machine code to jump to an unknown adress. In the next pass the linker will fill this unknown adress to the adress of the function Sin().
As said before: the compiler creates for each C-file a equivalent obj-file. The linker merges these and other obj's and/or lib's to an exe. Essentially an obj-file is an exe-file that have jumps to external defined functions not filled in. This is the reason you can't run obj-files (it will crash as soon as it wants to call the external function). An obj-file is an intermediate file in the compile/link process.
Aside: The above is over simplified, in reality it is more complex as described: actually tables of unknown adresses are writen to the obj-file so the linker knows which adresses it must fill in.
Rozis
|
|
|
|
|
Hi to all,
Could anyone please give me a hint, why we say, C follows top down and C++ bottom up approach.
Thanks
-----------------------------
I am a beginner
|
|
|
|
|
See here[^].
BTW: For this kind of questions you should first ask "uncle Google".
Regards
Nuri Ismail
|
|
|
|
|
Hi all,
i m using system tray icon for my application ,but when i run my application on windows xp the ballon of system tray icon not displayed,while its working fine in case of vista.
please help me how can i show ballon.
thanks in advance.
To accomplish great things, we must not only act, but also dream;
not only plan, but also believe.
|
|
|
|
|
Without seeing your code, I have no idea what the mistake you're making is.
But if it works under Vista, I would guess you're using either a vista only function (unlikely), or using Vista only members of NOTIFYICONDATA.
My code from waaaaaay back when:
NOTIFYICONDATA niData;
memset (&niData, 0, sizeof(niData);
niData.cbSize = sizeof (niData);
niData.hWnd = m_hFrameWnd;
niData.uID = 99;
niData.uFlags = NIF_ICON;
niData.hIcon = m_hTaskBarIcons [0];
Shell_NotifyIcon (NIM_ADD, &niData);
http://msdn.microsoft.com/en-us/library/bb773352%28VS.85%29.aspx[^], and I see that there is indeed a vista extension.
#if (NTDDI_VERSION >= NTDDI_VISTA)
HICON hBalloonIcon;
#endif
So, you pass the size of the vista only structure in cbSize, and XP goes "huh".
Read the rest of the article, and it will point you to a constant that defines the size of the structure that XP can handle.
Good luck,
Iain.
I have now moved to Sweden for love (awwww).
If you're in Scandinavia and want an MVP on the payroll (or happy with a remote worker), or need cotract work done, give me a job! http://cv.imcsoft.co.uk/[ ^]
|
|
|
|
|
I m taking help of this article for system tray icon
Adding Icons to the System Tray[^]
To accomplish great things, we must not only act, but also dream;
not only plan, but also believe.
|
|
|
|
|
It should work on XP.
Do you have SP2 installed?
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
What is the safe way to get the m_hThread handle?
One of few cases that construction hangs even if I change INFINITE to a second or so. It should be something with m_SomeThread object.
m_SomeThread is stored in MFC dialog.
Upon the user click, the AfxBeginThread is called, and m_SomeThread is assigned its return value.
I'm sure the thread does not hang in its body, as it posts the message to the dialog to report that it is finished.
Before creating another thread, the function waits for a single object in case user clicked too early and the thread has not yet terminated.
And one of few such calls the application freezes completely.
Чесноков
|
|
|
|
|
Did not really understand your question?
But I'm guess it has something to do with GetExitCodeThread[^].
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
|
Hi Yuriy,
Chesnokov Yuriy wrote: What is the safe way to get the m_hThread handle?
If the pointer to the thread is valid and the thread has not exited then the m_hThread handle is valid. You can use the GetExitCodeThread Function[^] to check if the thread is still active.
Chesnokov Yuriy wrote: And one of few such calls the application freezes completely.
What does your thread do? Are you interacting with a GUI thread?
Best Wishes,
-David Delaune
|
|
|
|
|
Hi Randor,
99% of cases the thread is already terminated, when the WaitForSingleObject() is called.
GetExitCodeThread() also uses CWinThread object handle.
I presume if the thread is terminated and the examination of the property m_SomeThread->m_hThread leads to some hanging in my case.
The thread simply do some math calculations as the user click the button, then prints the results of calculations to the GUI by means of PostMessage. The result is in the message params and GUI MFC juts put that result into the main dialog window.
So the user click the button, thread do some clever math in about 1-2 seconds, then the results are sent by PostMessage.
I did not want to go into disabling that button, while the thread is not finished, so I tried to use WaitForSingleObject() to make sure the thread will not be called twice if user clicks the button, before the thread terminated
Many thanks.
Чесноков
|
|
|
|
|
Here is what my instincts are telling me.
1.) You create your thread and it begins your small intensive calculation.
2.) Your parent thread is preempted and loses its CPU quantum slice before WaitForSingleObject is called.
3.) Your calculation is completed and the thread exits.
4.) Your parent thread resumes WaitForSingleObject and begins waiting on an invalid thread handle.
I would suggest the following:
1.) Create your thread suspended.
2.) Duplicate the thread handle.
3.) Wait on the duplicated handle.
4.) Resume the thread.
Let me know if it solves your problem.
Best Wishes,
-David Delaune
|
|
|
|
|
Randor wrote: 1.) Create your thread suspended.
2.) Duplicate the thread handle.
3.) Wait on the duplicated handle.
4.) Resume the thread.
Better to create the thread suspended, set the CWinThread::m_bAutoDelete to FALSE and then resume the execution of the thread.
The CWinThread object will normally destroy itself when the thread exits and consequently close the thread handle. This is prevented by setting m_bAutoDelete to FALSE .
But it also means that the caller is responsible for deleting the CWinThread object when the thread has finished.
As always: more info here[^].
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Hi Roger,
Thanks for the comment. Yes what you have described is another valid method to avoid waiting on an invalid thread handle. Describing it as 'better' sounds like an opinion.
Best Wishes,
-David Delaune
|
|
|
|
|
Hi David,
Randor wrote: Describing it as 'better' sounds like an opinion.
Mmmm, it may be so, but I'd like to clarify my opinion.
If the OP's problem was that he called ::WaitForSingleObject() with an invalid handle, it would return immediately with WAIT_FAILED , so this cannot be the problem. If the handle is still valid ::WaitForSingleObject() will either return zero or wait as expected.
Your suggestion to duplicate the handle is to circumvent the fact that CWinThread will close the handle in its destructor, unless the m_bAutoDelete member is set to FALSE . In this case my opinion of 'better' is to fix it the MFC way since it was introduced by MFC.
I think it's cleaner and hence 'better', but whether that's 'better' or not is a matter of opinion.
For what it's worth I think the OP has created some kind of race condition that may end up in a deadlock where the spawned thread sends a message to the main thread. In the message handler call chain he then waits for the thread to finished.....
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Roger Stoltz wrote: If the OP's problem was that he called ::WaitForSingleObject() with an invalid handle, it would return immediately with WAIT_FAILED
This is not completely correct. The NT kernel recycles both window and thread identifiers (HANDLES). You can easily test this by creating a test dialog with 2 buttons. On the first button create a thread and on the second button end the thread. Rapidly press the buttons and observe the newly created thread sometimes has the same handle value in your traced output. It is the same for window handles... when they are closed the same value can be assigned to a window created in the near future.
An excerpt from: The Birth of a Thread: CreateThread[^]
Please do not make any assumptions about this identifier; all that is guaranteed is that while the thread is running, no other thread will ever have the same ID. The ID may be recycled later on after the thread has terminated.
Multithreading for Rookies[^]
Give Me a Handle, and I'll Show You an Object[^]
1.) The benefit of your option is the engineer does not need to call DuplicateHandle. On the negative side your option requires the engineer to manually perform the thread cleanup.
2.) The benefit of the other option is the engineer does no cleanup because m_bAutoDelete defaults to TRUE. On the negative side the engineer has to call DuplicateHandle and then CloseHandle when he is done waiting.
Anyway, this debate is meanlingless. If the presented scenario is what is actually occuring then both options presented are good options. This is the beauty of the internet and sites like codeproject.com where professionals can exchange ideas and their experience.
Best Wishes,
-David Delaune
|
|
|
|
|
Randor wrote: The NT kernel recycles both window and thread identifiers (HANDLES).
Yep, I know that it does.
I don't see how this is relevant in this scenario though; even if the handle gets recycled it can only have one state in the aspect of valid or invalid when ::WaitForSingleObject() is called, which would mean that if the handle should happen to be invalid when ::WaitForSingleObject() is called it would return WAIT_FAILED. That's why I still think my previous statement is correct even though you seem to think not.
Additionally, as I understood it, the OP waits on the thread handle before creating another worker thread (as he should).
Randor wrote: If the presented scenario is what is actually occuring then both options presented are good options.
Of course!
Randor wrote: Anyway, this debate is meanlingless.
Naah, you provided a perfectly acceptable meaning yourself:
Randor wrote: This is the beauty of the internet and sites like codeproject.com where professionals can exchange ideas and their experience.
Exactly and I really enjoyed our little discussion.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Roger Stoltz wrote: I don't see how this is relevant in this scenario though
Is it *very* relevant. I am asserting that there is a small chance that immediately following thread termination it is possible for the same identifier to be assigned to another thread or kernel object. If you like I can create a sample application which continuously spawns/terminates a self deleting thread and then force a context switch before calling WaitForSingleObject. The alertable wait state will return 99% of the time and eventually deadlock. The cause of the deadlock will be a valid handle which is invalid in the context of the process calling WaitForSingleObject. I guess it would be better to use a different terminology as invalid seems to be confusing you.
As I have previously mentioned both of our excellent recommendations will avoid the deadlock.
Best Wishes,
-David Delaune
|
|
|
|
|
Well, what I have is a button click code:
1. if (m_SomeThread != 0) goto 2.
2. WaitForSingleObject(m_SomeThread->m_hThread, INFINITE);
3. m_SomeThread = AfxBeginThread(...)
The thread starts immediatly.
What I understood is if you create thread suspended and set autodelete to false, it will not be destroyed as the thread finishes.
In that case m_SomeThread->m_hThread will be valid and will not hang the GUI?
In that case it needs additional explicit thread destruction between 2. and 3. clauses.
Чесноков
|
|
|
|
|
Hi Yuriy,
Yes you understand correctly. The thread handle will be valid if m_bAutoDelete is set to FALSE. You will need to perform cleanup yourself of the m_SomeThread object.
Best Wishes,
-David Delaune
|
|
|
|
|
Randor wrote: As I have previously mentioned both of our excellent recommendations will avoid the deadlock.
David, no offence taken!
I find it interesting and there's a possibility that someone might learn something and it could be me.
However, I think you have misread my previous post (or possibly posts).
I figure this as I am still under the impression that the OP waits on the thread handle before spawning a new thread, as I've stated previously.
- or -
Do you really mean that you have experienced a scenario where you have a handle that:- you provide as argument to e.g.
::WaitForSingleObject() - is valid so the waiting function doesn't return
WAIT_FAILED immediately - has not assumed a signalled state (which would make the waiting function return immediately)
- becomes signalled, closed and recycled behind scenes
in a way that makes the waiting function hang?
(This is how I interpret your statement.)
I must say I seriously doubt that as it would mean a catastrophic design flaw of the synchronization mechanism of the operating system in my opinion.
Randor wrote: If you like I can create a sample application which continuously spawns/terminates a self deleting thread and then force a context switch before calling WaitForSingleObject. The alertable wait state will return 99% of the time and eventually deadlock.
If you are able to do that and wait on the thread handle before creating a new thread, I'd be delighted to see it.
I will even try and create such an abomination myself.
But if this is the case I don't see how any of our proposed solutions may prevent this deadlock.
Randor wrote: The cause of the deadlock will be a valid handle which is invalid in the context of the process calling WaitForSingleObject. I guess it would be better to use a different terminology as invalid seems to be confusing you.
Well, I wasn't confused until I read the underlined part above. But the confusion is more about what you mean rather than whether a handle is valid or invalid.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|