|
This only happens... the bug in my release version of the the DLL when I run my debug thru VS its fine
Just so I understand the ESP or Stack pointer points to the Top of the Stack which has the paramters
to the functions afterwards are the Local Varibles of the Function
Global Variables are pointed to by the data segment register
(I am a Mainframe Assembler programmer by trade) knowing Assebmler or X6 Masm I guess helps especially when
There is a bug only in release version of the app as that seems to be the only way to see the values of the
Variables
Below is the Function.... This the fuction definition --> int make_num(char *&);
int make_num(char *& str)
{
char holdstr[255]; // allocate a large buffer
int i =0, number;
for (; *str != ','; str++)
{
if((char) *str >= 0x30 || (char) *str <= 39)
{
holdstr[i] = (char) *str;
i++;
}
}
holdstr[i] = NULL;
number = atoi((const char *)&holdstr[0]);
return number;
}
Thanks much
|
|
|
|
|
---> holdstr[i] = NULL; This is the culprit how come this statement didn't generate any MASM instructions ??
number = atoi((const char *)&holdstr[0]);
0037147D lea eax,[esp+4]
00371481 push eax
00371482 mov byte ptr [esp+esi+8],0
00371487 call dword ptr [__imp__atoi (37204Ch)]
|
|
|
|
|
Thanks!
The stack frame on entry to the function should look something like this
(after the stack frame is built, working downward in memory):
4 bytes: Passed reference argument (passed as a pointer probably)
4 bytes: Return address
256 bytes: local array
<--- esp points here
The compiler is free to align the local variables and add any integers
or whatever it needs for the stack frame, so to rely on a certain esp value
would require knowing exactly how the compiler builds the stack frame, which
will vary between compilers and compiler settings.
That aside, you found the culprit. I'm not sure why the code to add the null terminator
wouldn't be in the compiled code!
Maybe try this - add symbolic debug info to your release build configuration.
Then when you run it in the debugger you can still debug easy.
adding debug symbols to release builds[^]
Also for what it's worth, you can simplify this line:
number = atoi((const char *)&holdstr[0]);
to
number = atoi(holdstr);
I'll take a look at it here - please let me know what you find!
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thankx so much right now debugging the release version
1)it seems that make_num is not returning a Value
I read that article regarding bugs in the release version of a application and... When I build a Release I also generate PDB('s) dont know the difference between the Debug and release Version of the excutables
I am Basically adding a DLL to a existing project
This is another issue but when I run the debug version of app it goes into a spin Loop so Debugging it I have used the rlease exe/DLL with PDB that VS created it seems that any Local symbol Symbols that require the Stack Frame
I have a hard time displaying using the release exe/dll(s) however using the Debug exe/dll I cann't get anywhere but this is a different issue
I am on the east coast and its 12:30 am here so I going to try to finish debugging this tommorow after work (work is MainFrame Stuff) really really appreciate your help
|
|
|
|
|
Also, what is the code used to export and inport the function?
C or C++ compiled?
Just to test with same configuration.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I'm in and out today setting up a show booth...
I had one quick note until I know your build configuration...
If you haven't already, make sure that the source string passed to the function
always has a comma ',' in it within 254 characters.
I passed a NULL terminated string to the function the first time I called it and
forgot to look at the loop termination logic I stopped it before it crashed but
single stepping through as it looped away wasn't good. As always that behavior is undefined.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
The atoi function seems to be giving me all kinds of grief
number = atoi(holdstr);
0037147D lea eax,[esp+4]
00371481 push eax
00371482 mov byte ptr [esp+esi+8],0
00371487 call dword ptr [__imp__atoi (37204Ch)]
When I cut'n paste this code the breakpoint was sitting on push inst
As you can see from the register value of eax
EAX = 0012FB18 EBX = 00000000 ECX = 0012FC3C EDX = 00729BEE ESI = 00000003 EDI = 78144BA8 EIP = 00371481 ESP = 0012FB14 EBP = 0012FF10 EFL = 00000246
Is a valid character string representation of 300
0x0012FB18 33 30 30 01 c0 c4 4a e4 18 0d c2 e3 10 00 12 00 00 ab 2f a3 a0 ab 4e 80 ff ff ff ff 00 00 02 00 00 50 fd
When I step by the call to atoi
00371487 call dword ptr [__imp__atoi (37204Ch)]
return number;
}
0037148D mov ecx,dword ptr [esp+108h] <--- currently here
The EAX register has the value I want X'12C' = decimal 300 However it never gets moved to number
Does I need to use something Like setlocale to get atoi working
Thankx
EAX = 0000012C EBX = 00000000 ECX = 00000020 EDX = 00000005 ESI = 00000003 EDI = 78144BA8 EIP = 0037148D ESP = 0012FB10 EBP = 0012FF10 EFL = 00000206
|
|
|
|
|
Sorry
My debug and release configuration e.g compiler options linker option that I had changed while debugging
I didn't make those same changes in release
I still have problems
but I am further along
Thankx
|
|
|
|
|
I am trying to create shell context menu , I want to dispaly the path of file that on the right click of my menu item. Program displaying the path of file very well except the shortcut file path(.lnk file).
When I click on .lnk file, It display the target file path but I want shortcut file path, even this is also a file.
I asked this quetion before and someone suggest me the following:
"The shell resolves the links before calling 'InvokeCommand()', so you always will receive the link target."
But some also suggest me:
"You can register as a handler for .lnk files. If you don't do that, the shell with automatically follow the link and pass the target file to your extension."
I tried the above method but I could not get the .lnk file path. So could you please tell me how to get the .lnk file path using shell context menu.
|
|
|
|
|
If you give meaningful subject, you may get help quickly.
Like "Getting path to .lnk file" or else.
Best Regards,
Suman
|
|
|
|
|
I have asked this question many times with meaningful subject but nobody respond me.
|
|
|
|
|
They might not see your question who knows answer.
In that case, we cant bother anybody and we need to google or search in MSDN or look for some other way ourself..
I hope you will find solution soon
Best Regards,
Suman
|
|
|
|
|
pther wrote: I have asked this question many times with meaningful subject but nobody respond me.
Which could indicate to you that we may not know the answer. Continuing to ask the same question over and over will not change that.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Suppose you register the extension handler under both * and .lnk as follows,
NoRemove lnkfile<br />
{<br />
NoRemove ShellEx<br />
{<br />
NoRemove ContextMenuHandlers<br />
{<br />
ForceRemove Myshell = s '{B3490870-0081-45C4-AE05-C4B7E788BC29}'<br />
}<br />
}<br />
}<br />
<br />
NoRemove *<br />
{<br />
NoRemove ShellEx<br />
{<br />
NoRemove ContextMenuHandlers<br />
{<br />
ForceRemove Myshell = s '{B3490870-0081-45C4-AE05-C4B7E788BC29}'<br />
}<br />
}<br />
}
The Initialize()function will be called twice. In the first call, it will passing target files name. But when it gets called for the second time, you will get the path of the lnk.
|
|
|
|
|
I also tried this too and I put a messagebox to display the selected file path. But it appears only once not twice.
my code for Initialize()
<br />
<br />
HRESULT __stdcall CCoMenHandler::Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID)<br />
{<br />
if(pidlFolder)<br />
m_pIDFolder = pidlFolder;<br />
<br />
if (m_pDataObj)<br />
m_pDataObj->Release(); <br />
<br />
if (pdtobj)<br />
{<br />
m_pDataObj = pdtobj;<br />
pdtobj->AddRef();<br />
} <br />
else<br />
{<br />
return E_FAIL;<br />
}<br />
<br />
g_szSelectedFiles.RemoveAll();<br />
<br />
if (pdtobj) <br />
{<br />
pdtobj->AddRef();<br />
<br />
STGMEDIUM medium;<br />
FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};<br />
<br />
HRESULT hr = pdtobj->GetData (&fe, &medium);<br />
<br />
if (FAILED (hr))<br />
{<br />
g_bRecyleBin=TRUE;<br />
GetRecycleBinFiles();
return ;<br />
}<br />
else<br />
g_bRecyleBin=FALSE;<br />
<br />
char path[MAX_PATH];<br />
<br />
UINT fileCount = DragQueryFile((HDROP)medium.lpszFileName, 0xFFFFFFFF,path, MAX_PATH);<br />
<br />
if (fileCount>0)<br />
{<br />
g_szSelectedFiles.SetSize(fileCount);<br />
<br />
for (UINT i=0;i<fileCount;i++) <br />
{<br />
memset(path, 0, MAX_PATH);<br />
if (DragQueryFile((HDROP)medium.lpszFileName, i, path, MAX_PATH)) <br />
{<br />
g_szSelectedFiles.SetAt(i, path);<br />
AfxMessageBox(path);<br />
<br />
<br />
}<br />
<br />
}<br />
g_szSelectedFiles.FreeExtra();<br />
}<br />
ReleaseStgMedium(&medium);<br />
} return S_OK;<br />
}<br />
So how could I get it.
|
|
|
|
|
pther wrote: I put a messagebox
Did u check by putting a break point in the first line of Initialize() function?
In your code message box in the end. There is a chance that some of your checking might have failed and the control might have returned before the messagebox. So just for debugging purpose modify your initilaze function such that in contains a AfxMessageBox.
HRESULT __stdcall CCoMenHandler::Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID)
{
AfxMessageBox( _T("Initialize called"));
return S_OK;
}
In this case also if only one message box came, paste the rgs file content here.
|
|
|
|
|
Thank you It is working for link file. But not working for Internet Shortcut file.
I am so thankful to you. I hope you will also assist me to get it.
|
|
|
|
|
pther wrote: But not working for Internet Shortcut file.
For that i think u need to register under the InternetShortcut key. I didnt try
NoRemove InternetShortcut
{
NoRemove ShellEx
{
NoRemove ContextMenuHandlers
{
ForceRemove Myshell = s '{B3490870-0081-45C4-AE05-C4B7E788BC29}'
}
}
|
|
|
|
|
Naveen, You help me a lot .
i am Very Very Thankful to you.
May I get your personal email id, if you do not mind.
|
|
|
|
|
Another crappy Indian programmer who cant work it out for themselves!
Morality is indistinguishable from social proscription
|
|
|
|
|
Hello everyone,
Why it is useless for any inheritance in Pimpl idiom? Here is the source, but no detailed reasons are provided.
http://www.gotw.ca/gotw/024.htm
--------------------
- make XImpl entirely the class that X would have been, and write X as only the public interface made up entirely of simple forwarding functions (a handle/body variant).
This is useful in a few restricted cases, and has the benefit of avoiding a back pointer since all services are available in the pimpl class. The chief drawback is that it normally makes the visible class useless for any inheritance, as either a base or a derived class.
--------------------
thanks in advance,
George
|
|
|
|
|
I can reply this. But please wait for me to type because I can not copy-and-paste.
Maxwell Chen
|
|
|
|
|
Can you provide a link, Maxwell? I can look up by myself.
regards,
George
|
|
|
|
|
The below is the original Pimpl model. The opaque pointer is the private member.
To test this with Visual C++ (2005), you need to put the declarations of class X and class X::XImpl with their member function prototypes in individual .h files, and put the implementations of member functions in individual .cpp files.
class X
{
private:
class XImpl;
XImpl* pimpl_;
public:
bool Foo(long);
protected:
int Bar(short);
};
class X::XImpl
{
public:
bool Function();
};
bool X::Foo(long v)
{
return pimpl_->Function();
}
bool X::XImpl::Function()
{
return true;
}
What does it mean To make XImpl entirely the class X would have been?
That is, you move X::Foo and X::Bar into class X::XImpl .
Code snippet below.
class X2
{
private:
class XImpl;
XImpl* pimpl_;
public:
bool Foo(long);
};
class X2::XImpl
{
public:
bool Function();
protected:
int Bar(short);
};
How will we use this revision? Still the same.
X2 obj;
if(obj.Foo() ) {
}
So now we talk about the inheritance. See the comments in the code snippet below.
class Y : public X2
{
public:
bool Test() {
return false;
}
};
Maxwell Chen
modified on Tuesday, March 18, 2008 4:04 AM
|
|
|
|
|
Thanks for providing a comprehensive sample, Maxwell!
1.
One question, why do you want to call Bar and Pimpl in method Test of class Y? If we put something (like Bar) in Pimpl part, it means it is not visible. So, I think it does not make senses to access Bar if it is in Pimpl part. Any comments?
2.
I think you can still access Foo in class Y, right?
regards,
George
|
|
|
|