代码之家  ›  专栏  ›  技术社区  ›  tbridge

VS2008调试:System.ArgumentException?

  •  3
  • tbridge  · 技术社区  · 14 年前

    问题是: 我有一个表单项目,它实例化了一个在单独的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;
    }
    

    正如您可能想象的那样,这使得调试我的应用程序变得非常困难:)非常感谢您的帮助。

    2 回复  |  直到 8 年前
        1
  •  4
  •   Richard Flamsholt    14 年前

    这不是一个这样的答案,但一些深入观察窗口vs调试打印输出之谜。

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

    因此,这个表达式求值器可能无法正确处理来自不安全DLL的类型,这一点我自己似乎也模糊地记得。作为一个“轻量级编译器”,它当然有一些缺点,这可能是其中之一。

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

        2
  •  0
  •   James King    14 年前

    你能检查一下你的配置管理器并确认所有的项目都编译成“任何CPU”吗?很有可能,但我知道有人也有类似的问题,我模糊地记得他有一个项目被设置为x86和任何CPU的混合体。