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

这不是一个答案,而是对 Watch-window 与 Debug-printout 之谜的一些见解。

Visual Studio 中的 Watch 窗口structList使用内置的托管表达式评估器评估您的输入,例如。因此,作为运行时解析器,它与编译器本身完全不同,并且只理解表达式的一个子集。你可以在这里阅读它的详细描述。

因此,有可能——我似乎隐约记得自己曾经历过——这个表达式求值器无法正确处理来自不安全 DLL 的类型。作为一个“轻量级编译器”,它确实有一些缺点,这可能就是其中之一。

另一方面,Debug.WriteLine()工作正常,因为传递给它的表达式在编译时由 C# 编译器本身处理。

于 2010-11-12T23:44:33.650 回答
0

您可以检查您的配置管理器并确认所有项目都编译为“任何 CPU”吗?远射,但我认识一个有类似问题的人,我隐约记得他的项目设置为 x86 和 Any CPU 的混合。

于 2010-11-12T22:53:32.267 回答