|
I suspected the same thing but, like you, can't pinpoint the exact problem. That's why I think knowing where things go wrong inside MFC might help.
Perhaps it's possible that different compiler settings were used in the EXE and the DLL and this caused the layout of the CDC class differ.
Or perhaps it's a mixed allocator problem: class CDC in the EXE allocates some data on its heap the the DLL free it on a different heap.
It would probably be a good idea to pass the raw HDC when passing a DC between modules.
Steve
|
|
|
|
|
OK, the error is in the CDC class. The compiler stops in the function OffsetViewportOrg!
|
|
|
|
|
Perhaps you can quote the file/line (and MFC version) and paste in some code surrounding the fault.
Steve
|
|
|
|
|
Ok, here is the function where the debugger stops (wingdi.cpp, MFC 7.1, VS2003 SP1):
CPoint CDC::SetViewportOrg(int x, int y)<br />
{<br />
ASSERT(m_hDC != NULL);<br />
CPoint point;<br />
<br />
if (m_hDC != m_hAttribDC)<br />
VERIFY(::SetViewportOrgEx(m_hDC, x, y, &point));<br />
if (m_hAttribDC != NULL)<br />
VERIFY(::SetViewportOrgEx(m_hAttribDC, x, y, &point));<br />
return point; <<<<<<<<<<<<<<<<Here stops the debugger !!!???<br />
}
I can't imagine why the debugger/program stops at this line...?
|
|
|
|
|
Thank you for your answer, I tried your recommendation...
1) --> Pointer is valid
2) --> works fine
3) --> ?
|
|
|
|
|
I suggest you side step the problem as follows:
1. Change the signature of the DLL function as follows:
int WINAPI PaintSpecialGraphics(HDC hDC);
2. Adjust the implementaion in the DLL so it looks like this:
int WINAPI PaintSpecialGraphics(HDC hDC)
{
CDC dc;
dc.Attach(hDC);
dc.Detach();
}
3. Make the call like this:
CPaintDC dc(this);
PaintSpecialGraphics(dc);
I suspect you can't use MFC classes across DLL boundries. Here are some possible reasons:
- MFC's handle map implementation.
- Different heaps.
- Different compiler settings in EXE and DLL.
Steve
|
|
|
|
|
Stephen Hewitt wrote: I suspect you can't use MFC classes across DLL boundries. Here are some possible reasons:
- MFC's handle map implementation.
- Different heaps.
- Different compiler settings in EXE and DLL.
Does this mean, that there is no way to exchange data (pointer to mfc objects) between mfc dlls?
My concept is to exchange cobject dervied classes (pointer) between my application and a mfc-based calculation dll..
|
|
|
|
|
It depends on how the classes are implemented and packaged. Consider this example:
class CExample
{
public:
int GetNum() { return g_Number; }
}
In this class the CExample::GetNum method access a global variable. If you include this class into an EXE and a DLL then the version in the EXE will access a global in the EXE; but when called from the DLL it will access a global (of the same name) in the DLL. Problems will probably ensue. There are ways around this issue but perhaps the MFC classes are simply not designed to be passed between module boundries (like this class). Unless you know it is same to do this the only safe assumption is that you can't.
Steve
|
|
|
|
|
Hi!
I have a problem with a button I have created dynamically in an SDI application in MFC.
Its purpose is to terminate the application (an Exit button). It works perfectly when I click on it, but what I want to do is make it close my application when I press the Enter key. It just doesn't work, even though the button has focus. It works when I have a dialog based application, but I'm not interested in that. I want it to be an SDI application. A solution I have found is to close the application by calling PostQuitMessage method when I press the Enter key and my button has focus, but I'm interested in a more simple and elegant way if possible.
Any ideas would be greatly apreciated!
Thanks in advance!
|
|
|
|
|
One way is, make that button of type CMyButton, derived from CButton, handle WM_KEYDOWN message.
-- modified at 3:00 Friday 1st September, 2006
|
|
|
|
|
|
Hi all.
How I prevent others to access my process via interprocess communication?
I know that when I want to open a process using IPC I can use OpenProcess function and inform the desired access. How I can prevent every access, i.e., no PROCESS_VM_READ access, no PROCESS_VM_WRITE acess, etc etc.
And, How i can deny ipc access for all process but allow it to a specif process?
Thx in advance.
Best regards,
Marco Alves.
|
|
|
|
|
First, the process access as you described is not IPC. It's usually controlled by process's security attributes. You may call SetSecurityInfo() to define security of a process. Hope this link can help.
On the other hand, IPC is the communication between two processes. Thus, it's mutual. If your process does not respond to IPC, nobody can do anything to hurt it.
Best,
Jun
|
|
|
|
|
In a recent post Jeremy Falcon[^] provided a link to a white paper about DLL best practices. Basically the paper outlined the does and don'ts of the DllMain function. One of the references cited in that paper is http://blogs.msdn.com/oldnewthing/archive/2004/01/27/63401.aspx[^] where the author says never create a window in response to DLL_PROCESS_ATTACH.
Now this brings up a question in my mind. I have a dll where I have declared a global class that calls the CreateWindow() API in it's constructor. While the window is technically not created in DllMain, it does get created every time the dll is loaded but before DllMain is called.
Everything seems to be working fine so far, but am I asking for trouble using this approach? Or is the fact the window is not created in DllMain mean that I am avoiding the locking issues mentioned in those papers? I guess my question can be summed up as: Is this a safe way to create global window objects in a dll?
Global class:
class CDllWindow
{
public:
CDllWindow();
private:
HWND DllWindow;
};
CDllWindow::CDllWindow()
{
DllWindow = CreateWindow(...);
}
Dll cpp file:
#include "DllWindow.h"
CDllWindow DllWindow;
BOOL APIENTRY DllMain(HMODULE, DWORD, LPVOID)
{
return TRUE;
}
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|
|
You are asking for trouble in 2 different ways here.
First, using operations like CreateWindow in your constructor is dangerous since if CreateWindow fails, you have not completed your construction of the object. It is safer to initialize any variables and have a separate Create function to create your window.
Second, Doing this as part of the static memory allocation for your Dll can cause problems if the DLL fails to load properly. Basically, the same arguments for not calling CreateWindow inside your DllMain apply to calling it before it gets called as well.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Zac Howland wrote: First, using operations like CreateWindow in your constructor is dangerous since if CreateWindow fails, you have not completed your construction of the object. It is safer to initialize any variables and have a separate Create function to create your window.
I disagree with you on that one. If CreateWindow fails the DllWindow member will be NULL, but the CDllWindow class object will still be successfully created.
Zac Howland wrote: Doing this as part of the static memory allocation for your Dll can cause problems if the DLL fails to load properly. Basically, the same arguments for not calling CreateWindow inside your DllMain apply to calling it before it gets called as well.
That is what I was afraid of, but I was hoping it was not the case. Oh well, I guess I will have to think up a different method to do what I want.
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|
|
Ok, taking your two points into consideration I think I have come up with a solution that should work. I still disagree with your first point on a general level, but in this instance a seperate Create function is just what I need.
Thanks for your input
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|
|
The rule is actually "Don't do anything dangerous while the loader lock is taken." This is usually shortened to "Don't do anything dangerous in DllMain() " because that version is more easily understood.
Your DllMain() is only one part of the module initialization. There is CRT code that runs before DllMain() (by default it's called DllMainCRTStartup() IIRC) that is responsible for constructing globals in the DLL. All that code runs while the loader lock is taken, so it must not do anything that would cause a deadlock.
|
|
|
|
|
Thanks Mike
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|
|
Hello
Looks like my C++ is getting really rusty. While playing a bit in a console project the following code gave me a strange heap corruption error.
#include <iostream>
using namespace std;
void main()
{
char* MyText = new char;
cin>>MyText;
delete[] MyText;
}
It's not even an exception. Sometimes it says "Windows have set a breakpoint in your application because of a heap error." And a break point appears somewhere in the iostream file.
Other times, an ugly error message appears saying "HEAP CORRUPTION DETECTED after a normal block. CRT detected that application wrote to memory after end of heap buffer.",
Any clue??
Regards
|
|
|
|
|
Nader Elshehabi wrote: char* MyText = new char;
cin>>MyText;
delete[] MyText;
new matches up with delete . new[] matches up with delete[] . Calling delete[] on something that was new 'd will result in a heap corruption.
To fix the problem:
void main()
{
char* MyText = new char;
cin>>MyText;
delete MyText;
}
or
void main()
{
char* MyText = new char[100];
cin>>MyText;
delete [] MyText;
}
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Hello
Thanks for replying.
Well, the first coder didn't work, while the second did. Yet, that makes a buffer of N chars. That's not what I want. What if the user inputs n+1 chars. I tried it and it made the same heap corruption error. Also what if I dynamically reallocate my array -or pointer-??
If you got more details or point me to some article about this issue, I'd be grateful.
Thanks again.
Regards
|
|
|
|
|
Nader Elshehabi wrote: Well, the first coder didn't work, while the second did.
The first code has another problem due to the fact that cin's operator>> will pull in 2 characters even if you only typed 1 (the character you typed and a '\0' to terminate the string). If you are only trying to pull in 1 character, the cin.getc() would work better.
Nader Elshehabi wrote: Yet, that makes a buffer of N chars. That's not what I want. What if the user inputs n+1 chars.
You will not be able to use the operator>> to do this (at least not yet ... as I said, the new proposal for the C++ standard has all overloaded operators that deal with char* now also overloaded for string). What you can do is iterate through it:
char ch;
string input;
while ((ch = cin.getc()) != '\n')
{
input += ch;
}
That will prevent any possibility of a buffer overflow issue, but will also be VERY slow (in comparison to pulling down a whole set of data at once).
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Hello
Thanks again for your reply! I got two more questions . Take a look at this code;
char* MyText = new char[5];
cin>>MyText;
MyText = new char[10];
delete[] MyText;
Now , I called a second new without deleting the first one. Is there a leak here??
What if I didn't call a delete at all!! Once my program finishes and closes. Will the memory be freed?
Or will it be permanently locked until reboot?
Regards
|
|
|
|
|
Nader Elshehabi wrote: Is there a leak here??
Yes.
Nader Elshehabi wrote: Will the memory be freed?
Yes.
"Talent without discipline is like an octopus on roller skates. There's plenty of movement, but you never know if it's going to be forward, backwards, or sideways." - H. Jackson Brown, Jr.
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|