If your code is working in 32 bit and you are getting this error while you try to build your shell extension in 64 bit than here is the solution. The 64-bit header defines the IContextMenu::GetCommandString function with a different signature than the 32 bit header.
GetCommandString(UINT_PTR,UINT,UINT *,LPSTR,UINT) ---- 64-bit
vs.
GetCommandString(UINT,UINT,UINT *,LPSTR,UINT) - ----32-bit
So change GetCommandString signature according to your build configuration. This is what I did in my sample app and its working fine in 64 bit OS.
Monday, December 14, 2009
Saturday, December 12, 2009
Memory management : stack vs heap
The memory a program uses is typically divided into four different areas:
• The code area, where the compiled program sits in memory.
• The globals area, where global variables are stored.
• The heap, where dynamically allocated variables are allocated from.
• The stack, where parameters and local variables are allocated from.
The heap:
The heap (also known as the “free store”) is a large pool of memory used for dynamic allocation. In C++, when you use the new operator to allocate memory, this memory is assigned from the heap.
example-
int *pArray = new int[10]; // pArray is assigned 40 bytes from the heap
Because the precise location of the memory allocated is not known in advance, the memory allocated has to be accessed indirectly — which is why new returns a pointer. You do not have to worry about the mechanics behind the process of how free memory is located and allocated to the user. However, it is worth knowing that sequential memory requests may not result in sequential memory addresses being allocated!
When a dynamically allocated variable is deleted, the memory is “returned” to the heap and can then be reassigned as future allocation requests are received.
The heap has advantages and disadvantages:
1) Allocated memory stays allocated until it is specifically deallocated (beware memory leaks).
2) Dynamically allocated memory must be accessed through a pointer.
3) Because the heap is a big pool of memory, large arrays, structures, or classes should be allocated here.
The stack
In computer programming, a stack is a container that holds other variables (much like an array). However, whereas an array lets you access and modify elements in any order you wish, a stack is more limited.
The operations that can be performed on a stack are :
1) Look at the top item on the stack (usually done via a function called top())
2) Take the top item off of the stack (done via a function called pop())
3) Put a new item on top of the stack (done via a function called push())
A stack is a last-in, first-out (LIFO) structure. The last item pushed onto the stack will be the first item popped off. If you put a new plate on top of the stack, anybody who takes a plate from the stack will take the plate you just pushed on first. Last on, first off. As items are pushed onto a stack, the stack grows larger — as items are popped off, the stack grows smaller.
The stack in action:
Because parameters and local variables essentially belong to a function, we really only need to consider what happens on the stack when we call a function.
Here is the sequence of steps that takes place when a function is called:
1. The address of the instruction beyond the function call is pushed onto the stack. This is how the CPU remembers where to go after the function returns.
2. Room is made on the stack for the function’s return type. This is just a placeholder for now.
3. The CPU jumps to the function’s code.
4. The current top of the stack is held in a special pointer called the stack frame. Everything added to the stack after this point is considered “local” to the function.
5. All function arguments are placed on the stack.
6. The instructions inside of the function begin executing.
7. Local variables are pushed onto the stack as they are defined.
When the function terminates, the following steps happen:
1. The function’s return value is copied into the placeholder that was put on the stack for this purpose.
2. Everything after the stack frame pointer is popped off. This destroys all local variables and arguments.
3. The return value is popped off the stack and is assigned as the value of the function. If the value of the function isn’t assigned to anything, no assignment takes place, and the value is lost.
4. The address of the next instruction to execute is popped off the stack, and the CPU resumes execution at that instruction.
Typically, it is not important to know all the details about how the call stack works. However, understanding that functions are effectively pushed on the stack when they are called and popped off when they return gives you the fundamentals needed to understand recursion, as well as some other concepts that are useful when debugging.
Stack overflow:
The stack has a limited size, and consequently can only hold a limited amount of information. If the program tries to put too much information on the stack, stack overflow will result. Stack overflow happens when all the memory in the stack has been allocated — in that case, further allocations begin overflowing into other sections of memory.
Stack overflow is generally the result of allocating too many variables on the stack, and/or making too many nested function calls (where function A calls function B calls function C calls function D etc…) Overflowing the stack generally causes the program to crash.
Here is an example program that causes a stack overflow. You can run it on your system and watch it crash:
int main()
{
int nStack[100000000];
return 0;
}
This program tries to allocate a huge array on the stack. Because the stack is not large enough to handle this array, the array allocation overflows into portions of memory the program is not allowed to use. Consequently, the program crashes.
The stack has advantages and disadvantages:
• Memory allocated on the stack stays in scope as long as it is on the stack. It is destroyed when it is popped off the stack.
• All memory allocated on the stack is known at compile time. Consequently, this memory can be accessed directly through a variable.
• Because the stack is relatively small, it is generally not a good idea to do anything that eats up lots of stack space. This includes allocating large arrays, structures, and classes, as well as heavy recursion.
This article is taken from www.learncpp.com. For more details you can refer to this site.
• The code area, where the compiled program sits in memory.
• The globals area, where global variables are stored.
• The heap, where dynamically allocated variables are allocated from.
• The stack, where parameters and local variables are allocated from.
The heap:
The heap (also known as the “free store”) is a large pool of memory used for dynamic allocation. In C++, when you use the new operator to allocate memory, this memory is assigned from the heap.
example-
int *pArray = new int[10]; // pArray is assigned 40 bytes from the heap
Because the precise location of the memory allocated is not known in advance, the memory allocated has to be accessed indirectly — which is why new returns a pointer. You do not have to worry about the mechanics behind the process of how free memory is located and allocated to the user. However, it is worth knowing that sequential memory requests may not result in sequential memory addresses being allocated!
When a dynamically allocated variable is deleted, the memory is “returned” to the heap and can then be reassigned as future allocation requests are received.
The heap has advantages and disadvantages:
1) Allocated memory stays allocated until it is specifically deallocated (beware memory leaks).
2) Dynamically allocated memory must be accessed through a pointer.
3) Because the heap is a big pool of memory, large arrays, structures, or classes should be allocated here.
The stack
In computer programming, a stack is a container that holds other variables (much like an array). However, whereas an array lets you access and modify elements in any order you wish, a stack is more limited.
The operations that can be performed on a stack are :
1) Look at the top item on the stack (usually done via a function called top())
2) Take the top item off of the stack (done via a function called pop())
3) Put a new item on top of the stack (done via a function called push())
A stack is a last-in, first-out (LIFO) structure. The last item pushed onto the stack will be the first item popped off. If you put a new plate on top of the stack, anybody who takes a plate from the stack will take the plate you just pushed on first. Last on, first off. As items are pushed onto a stack, the stack grows larger — as items are popped off, the stack grows smaller.
The stack in action:
Because parameters and local variables essentially belong to a function, we really only need to consider what happens on the stack when we call a function.
Here is the sequence of steps that takes place when a function is called:
1. The address of the instruction beyond the function call is pushed onto the stack. This is how the CPU remembers where to go after the function returns.
2. Room is made on the stack for the function’s return type. This is just a placeholder for now.
3. The CPU jumps to the function’s code.
4. The current top of the stack is held in a special pointer called the stack frame. Everything added to the stack after this point is considered “local” to the function.
5. All function arguments are placed on the stack.
6. The instructions inside of the function begin executing.
7. Local variables are pushed onto the stack as they are defined.
When the function terminates, the following steps happen:
1. The function’s return value is copied into the placeholder that was put on the stack for this purpose.
2. Everything after the stack frame pointer is popped off. This destroys all local variables and arguments.
3. The return value is popped off the stack and is assigned as the value of the function. If the value of the function isn’t assigned to anything, no assignment takes place, and the value is lost.
4. The address of the next instruction to execute is popped off the stack, and the CPU resumes execution at that instruction.
Typically, it is not important to know all the details about how the call stack works. However, understanding that functions are effectively pushed on the stack when they are called and popped off when they return gives you the fundamentals needed to understand recursion, as well as some other concepts that are useful when debugging.
Stack overflow:
The stack has a limited size, and consequently can only hold a limited amount of information. If the program tries to put too much information on the stack, stack overflow will result. Stack overflow happens when all the memory in the stack has been allocated — in that case, further allocations begin overflowing into other sections of memory.
Stack overflow is generally the result of allocating too many variables on the stack, and/or making too many nested function calls (where function A calls function B calls function C calls function D etc…) Overflowing the stack generally causes the program to crash.
Here is an example program that causes a stack overflow. You can run it on your system and watch it crash:
int main()
{
int nStack[100000000];
return 0;
}
This program tries to allocate a huge array on the stack. Because the stack is not large enough to handle this array, the array allocation overflows into portions of memory the program is not allowed to use. Consequently, the program crashes.
The stack has advantages and disadvantages:
• Memory allocated on the stack stays in scope as long as it is on the stack. It is destroyed when it is popped off the stack.
• All memory allocated on the stack is known at compile time. Consequently, this memory can be accessed directly through a variable.
• Because the stack is relatively small, it is generally not a good idea to do anything that eats up lots of stack space. This includes allocating large arrays, structures, and classes, as well as heavy recursion.
This article is taken from www.learncpp.com. For more details you can refer to this site.
Remote debugging in VS 2005 and latter.
To start remote debugging on a client machine you need to run the msvcmon.exe in remote client machine. Visual studio need not to be installed on client machine. To install the msvcmon.exe in your client machine and start debugging do the followings steps-
1. Find the "Remote Debugger" folder under your installation directory for visual studio 2005 "Common7\IDE\". If your running Visual Studio 2008 than the path will be "Microsoft Visual Studio 9.0\Common7\IDE\Remote Debugger".
2. Copy this entire directory to the client machine that is running your process. You can put it in any directly anywhere on the drive.
3. Make sure that you have copied the pdb file (program database) on the client machine where your binaries are located and the binaries from the same code base you are having in your dev machine.
4. Launch your application and than launch msvsmon.exe.
5. When you run msvcmon.exe you may get some dialog that pop up that indicate your Sharing and security model is set for guest, just click Yes. If your firewall block remote debugger than unblock it.
6. In the msvcmon.exe go to Tools/Options. Where the group box says Authentication Mode, select No Authentication, click on Allow any user to debug and click OK.
7. On your dev machine in Visual Studio go to Tools->Attach to process (Ctrl-Alt-P) and open up the Attach to Process dialog. Change the Transport to Remote (Native only with no authentication). In the Qualifier box browse for your client machine on the network.Once you find your target machine the Attach to Process dialog will refresh with the processes that are running on the other system.
8. Attach to you application and start debugging.
1. Find the "Remote Debugger" folder under your installation directory for visual studio 2005 "Common7\IDE\". If your running Visual Studio 2008 than the path will be "Microsoft Visual Studio 9.0\Common7\IDE\Remote Debugger".
2. Copy this entire directory to the client machine that is running your process. You can put it in any directly anywhere on the drive.
3. Make sure that you have copied the pdb file (program database) on the client machine where your binaries are located and the binaries from the same code base you are having in your dev machine.
4. Launch your application and than launch msvsmon.exe.
5. When you run msvcmon.exe you may get some dialog that pop up that indicate your Sharing and security model is set for guest, just click Yes. If your firewall block remote debugger than unblock it.
6. In the msvcmon.exe go to Tools/Options. Where the group box says Authentication Mode, select No Authentication, click on Allow any user to debug and click OK.
7. On your dev machine in Visual Studio go to Tools->Attach to process (Ctrl-Alt-P) and open up the Attach to Process dialog. Change the Transport to Remote (Native only with no authentication). In the Qualifier box browse for your client machine on the network.Once you find your target machine the Attach to Process dialog will refresh with the processes that are running on the other system.
8. Attach to you application and start debugging.
Friday, November 27, 2009
how to use an assembly in com server or c++
To make your assembly visible to com object you need to fulfill the following two requirements-
1. You have to generate the tlb file (type library) from your assembly. you can do it by using any one of the following utility provided by .net-
a).One utility is TLBEXP.EXE, the .Net Type Library Exporter. This command line utility takes as input the name of an assembly DLL file to be converted to a Type Library. The programmer can also specify the name of a Type Library file to be created.for Example -
tlbexp assembly.dll /out:tlb_name.tlb
b). 2nd one is REGASM.EXE. It does two task in a single shot. It generate the tlb and by the time register it as a com client. If you are using TLBEXP.exe than you have to do the 2nd step also.
2. Register your assembly using REGASM.EXE.
Once you have the tlb file and your assembly is registered as a com server you can simply start using it by importing the tlb file.
1. You have to generate the tlb file (type library) from your assembly. you can do it by using any one of the following utility provided by .net-
a).One utility is TLBEXP.EXE, the .Net Type Library Exporter. This command line utility takes as input the name of an assembly DLL file to be converted to a Type Library. The programmer can also specify the name of a Type Library file to be created.for Example -
tlbexp assembly.dll /out:tlb_name.tlb
b). 2nd one is REGASM.EXE. It does two task in a single shot. It generate the tlb and by the time register it as a com client. If you are using TLBEXP.exe than you have to do the 2nd step also.
2. Register your assembly using REGASM.EXE.
Once you have the tlb file and your assembly is registered as a com server you can simply start using it by importing the tlb file.
#import "tlb_name.tlb" raw_interfaces_only
Subscribe to:
Posts (Atom)