3

問題: 別のdllプロジェクトで定義されているクラスをインスタンス化するフォームプロジェクトがあります。このdllを使用するフォームアプリケーションを実行すると、すべてが完全に正常に実行されます、dllプロジェクトで定義されているタイプのオブジェクトを検査するためにブレークポイントを設定すると、ウォッチウィンドウにエラーが表示されます。

知っておくべき重要なこと:

  1. dllプロジェクトは、安全でない管理されていないコードを使用しています。
  2. この問題は、安全でない関数が呼び出される前に発生します。
  3. アンマネージコードのデバッグが有効になっています。
  4. シンボルがdll用にロードされていることを知っています。
  5. デバッガーによってロードされるdllのバージョンは、アプリケーションで使用されるものと同じです。
  6. 出力ディレクトリをクリーンアップして削除してから、再構築しました。
  7. 彼らは同じ.NETバージョンを使用しています。

例:これをウォッチウィンドウに追加すると、次のように表示MyDllType.SomePropertyされます(ウォッチウィンドウのみ):

'MyDllType.SomeProperty' threw an exception of type 'System.ArgumentException' Message: "Cannot find the method on the object instance."

ただし、同じ正確なポイントで追加Debug.Writeline(MyDllType.SomeProperty);した場合、例外は発生せず、出力コンソールに正しく表示されます。

さらに、dllプロジェクトで定義された構造体タイプのリストを作成してウォッチウィンドウに追加すると、次のように表示されます(ウォッチウィンドウのみ)。

// My Dll Project
public struct MyDllStruct
{
    public int x;
    public int y;
    public int z;
}

// Snippet from a function block in forms project
List<MyDllStruct> structList = new List<MyDllStruct>();

// Add a bunch of stuff to the list
// <-- Insert a breakpoint here
}

壊れstructListてウォッチウィンドウに追加すると、次のようになります。

Unable to evaluate the expression. Operation not supported. Unknown error: 0x8004f0ed.

ただし、もう一度Debug.Writeline(structList.Count);同じ正確なポイントで追加すると、例外は発生せず、カウントが出力コンソールに正しく表示されます。

完全な例

// My Dll Project
public class MyDllType
{
    public MyDLLType()
    {
        this.someProperty = 123456;
    }

    private int someProperty;
    public int SomeProperty
    {
        get{ return this.someProperty; }
        set{ this.someProperty = value; }
    }
}
public struct MyDllStruct
{
    public int x;
    public int y;
    public int z;
}

// My Forms Project
public class SomeController
{
    public SomeController()
    {
        this.dllType = new DllType();
        List<MyDllStruct> structList = new List<MyDllStruct>();

        // <-- For example, I get both aformentioned problems if i break here (or anywhere else these objects have been instantiated)
    }

    private MyDllType dllType;
}

ご想像のとおり、これによりアプリケーションのデバッグが非常に困難になっています:)助けていただければ幸いです。

4

2 に答える 2

4

これはそれ自体が答えではありませんが、ウォッチウィンドウとデバッグプリントアウトの謎についての洞察です。

Visual Studioの[ウォッチ]ウィンドウはstructList、組み込みのマネージ式エバリュエーターを使用して、入力を評価します。したがって、ランタイムパーサーとしては、コンパイラ自体とは完全に異なる獣であり、式のサブセットのみを理解します。あなたはそれの細かい説明をここで読むことができます。

したがって、この式エバリュエーターが安全でないDLLからの型を適切に処理できない可能性があり、これを自分で経験したことを漠然と覚えているようです。「軽量コンパイラ」としては確かにいくつかの欠点があり、これはおそらくそのうちの1つです。

一方、Debug.WriteLine()渡された式はコンパイル時にC#コンパイラ自体によって処理されるため、正常に機能します。

于 2010-11-12T23:44:33.650 に答える
0

構成マネージャーをチェックして、すべてのプロジェクトが「任意のCPU」にコンパイルされることを確認できますか?ロングショットですが、同様の問題を抱えている人を知っています。彼がx86とAnyCPUの組み合わせに設定されたプロジェクトを持っていたことをぼんやりと覚えています。

于 2010-11-12T22:53:32.267 に答える