문제

The Problem: I have a forms project which instantiates a class that is defined in a separate dll project. When running the forms application which uses this dll everything runs perfectly fine, however, when I set a breakpoint to inspect objects of types that are defined in the dll project I get errors in my watch window.

Some things that may be important to know:

  1. The dll project uses unsafe and unmanaged code.
  2. This problem occurs before any unsafe functions are called.
  3. Unmanaged code debugging is enabled.
  4. I know the symbols are loaded for the dll.
  5. I know the version of the dll loaded by the debugger is the same used by the application.
  6. I have cleaned and deleted the output directory then rebuilt.
  7. They are using the same .NET version.

Example: if I were to add this to my watch window MyDllType.SomeProperty I would see this (in the watch window only):

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

However, if I were to add Debug.Writeline(MyDllType.SomeProperty); at that same exact point then I would get no exception and it would be correctly displayed in the output console.

Furthermore: if I were to create a list of a struct type defined in the dll project and add it to my watch window I would see this (in the watch window only):

// 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
}

When i break and add structList to the watch window I get:

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

However, once again I were to add Debug.Writeline(structList.Count); at that same exact point then I would get no exception and it the count would be correctly displayed in the output console.

Full Example:

// 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;
}

As you could probably imagine, this is making it really hard to debug my application :) Any help would be much appreciated.

도움이 되었습니까?

해결책

This is not an answer as such, but some insight into the Watch-window vs Debug-printout mystery.

The Watch window in Visual Studio evaluates your input, say structList, using a built-in managed expression evaluator. As a runtime parser it is therefore a completely different beast than the compiler itself and only understands a subset of expressions. You can read a fine description of it here.

Therefore it's possible - and I seem to vaguely remember having experienced this myself - that this expression evaluator cannot properly handle types from an unsafe DLL. As a "lightweight compiler" it certainly does have some shortcomings, and this is possibly one of them.

On the other hand, Debug.WriteLine() works fine because the expression passed to it is processed at compile-time by the C# compiler itself.

다른 팁

Can you check your configuration manager and confirm that all projects compile to 'Any CPU'? Long shot, but I know someone who had a similar problem, and I vaguely to remember he had projects that were set to a mix of x86 and Any CPU.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top