I have the following MASM code:
.386
.model flat, stdcall
option casemap :none
include \masm32\include\masm32rt.inc
.data
NewLine db 13, 10, 0
.code
LibMain proc instance:dword,reason:dword,unused:dword
mov eax, 1
ret
LibMain endp
PrintMess proc
print "Printed from assembly"
invoke StdOut, addr NewLine
ret
PrintMess endp
TestReturn proc number:dword
mov eax, number
ret
TestReturn endp
End LibMain
With a simple .def file:
LIBRARY MyLib
EXPORTS PrintMess
EXPORTS TestReturn
And I'm calling PrintMess
and TestReturn
from C# as such:
[DllImport("MyLib")]
static extern void PrintMess();
[DllImport("MyLib")]
static extern int TestReturn(int num);
static void Main(string[] args) {
Console.WriteLine("Printed from C#");
PrintMess();
int value = TestReturn(30);
Console.WriteLine("Returned: " + value);
Console.ReadKey(true);
}
The very first time I ran it, it paused at Console.ReadKey(true)
and I get the expected output:
Printed from C#
Printed from assembly
Returned: 30
If I then make a change in my C# project, say TestReturn(30)
changed to TestReturn(50)
then it behaves strangely. The program terminates without error and does not pause on Console.ReadKey(true)
(it seems it doesn't even make it to that line) and this is my output:
Printed from C#
Printed from assembly
I have to rebuild the assembly project. Specifically I have to REbuild, if I do another regular build, the program continues to misbehave. When I do rebuild, the output and behavior returns to normal and reflects the number change in the output. My guess is that something is different between Build and Rebuild that's partially breaking the DLL.
Why do I have to rebuild and how I can I set it up so I don't have to?
Sometimes, Visual Studio will always rebuild projects, even though they have recently been built and there are no changes. If you build , and then run the project will build. If you haven't disabled the “projects out of date”-dialog, it will pop up and ask you to rebuild.
Rebuild: Deletes all compiled files and compiles them again irrespective if the code has changed or not. Clean solution: Deletes all compiled files (DLL and EXE file). You can see this YouTube video (Visual Studio Build vs. Rebuild vs.
Build and rebuild are two options available in Visual Studio. The main difference between build and rebuild in Visual Studio is that build helps to complete the code files which are changed while rebuild deletes all previously compiled files and compiles the solution from scratch ignoring anything done before.
@HansPassant is most probably correct but does not explain why you have to rebuild. @jacobaloysious is close.
VS is using what is called "hosting process" to ease and isolate debugging. when you debug test.exe
from VS, in fact you are actually debugging test.vshost.exe
, which loads your exe. host executable is not unloaded when you stop debugging, so your real executable. when you build your code without changing anything VS actually only does nothing but to check if files are up-to-date. VS thinks, if files are not changed, then there is no need to reload hosting process. if you rebuild, even if you have changed no code, you real executable is updated and this forces host process to be terminated and to be reloaded, along with your real executable.
I think, this process actually for speeding up start-up of debugging by preloading assembly code. you may try turning off "Enable the Visual Studio hosting process" in project properties. After that, you should be seeing you project working as expected.
Before you move further, realize that @HansPassant is correct and you have a corrupted stack, and as time goes by you project will fail in unexpected ways at unexpected times in most unpleasant ways possible. In most cases you application will throw exceptions that has no meaning, and in some cases you application will just vanish.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With