7

次の MASM コードがあります。

.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

シンプルな .def ファイルの場合:

LIBRARY MyLib
EXPORTS PrintMess
EXPORTS TestReturn

そして、私はC#から呼び出しPrintMessています:TestReturn

[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);
}

初めて実行したとき、一時停止しConsole.ReadKey(true)、期待される出力が得られました。

Printed from C#
Printed from assembly
Returned: 30

その後、C# プロジェクトに変更を加えた場合、変更したと言うと、TestReturn(30)奇妙TestReturn(50)な動作をします。プログラムはエラーなしで終了し、一時停止しませんConsole.ReadKey(true)(その行にさえ到達していないようです)。これが私の出力です。

Printed from C#
Printed from assembly

アセンブリ プロジェクトを再構築する必要があります。具体的には、再ビルドする必要があります。別の通常のビルドを行うと、プログラムは引き続き誤動作します。再構築すると、出力と動作が正常に戻り、数値の変更が出力に反映されます。私の推測では、DLL を部分的に壊している Build と Rebuild の間で何かが違うということです。

再構築する必要があるのはなぜですか?また、再構築する必要がないように設定するにはどうすればよいですか?

4

1 に答える 1

2

@HansPassant はおそらく正しいですが、再構築する必要がある理由を説明していません。@jacobaloysious は近いです。

VS は、いわゆる「ホスティング プロセス」を使用して、デバッグを容易にし、分離しています。VSからデバッグtest.exeすると、実際には実際にデバッグされtest.vshost.exe、exeがロードされます。デバッグを停止すると、ホスト実行可能ファイルはアンロードされないため、実際の実行可能ファイルがアンロードされます。何も変更せずにコードをビルドすると、VSは実際にはファイルが最新かどうかを確認するだけです。VS は、ファイルが変更されていなければ、ホスティング プロセスをリロードする必要はないと考えています。再構築すると、コードを変更していなくても、実際の実行可能ファイルが更新され、ホスト プロセスが強制的に終了され、実際の実行可能ファイルとともに再ロードされます。

この処理は、実際にはアセンブリ コードをプリロードしてデバッグの起動を高速化するためのものだと思います。プロジェクトのプロパティで「Visual Studio ホスティング プロセスを有効にする」をオフにしてみてください。その後、プロジェクトが期待どおりに機能していることがわかります。

先に進む前に、@HansPassant が正しく、スタックが破損していることを認識してください。時間が経つにつれて、プロジェクトは予想外のタイミングで予想外の方法で、可能な限り最も不快な方法で失敗します。ほとんどの場合、アプリケーションは意味のない例外をスローし、場合によってはアプリケーションが消えてしまいます。

于 2013-06-12T07:47:26.497 に答える