问题:
我有一个窗体项目,该实例化在单独的dll项目中定义的类.当运行使用此dll的表单应用程序时,一切运行都很好,但是,当我设置一个断点来检查dll项目中定义的类型的对象时,我在监视窗口中出现错误.
需要了解的一些重要事项:
> dll项目使用不安全且不受管理的代码.
>在调用任何不安全的功能之前,会发生此问题.
>启用非托管代码调试.
>我知道符号已为dll加载.
>我知道调试器加载的dll版本与应用程序使用的版本相同.
>我已经清理并删除了输出目录,然后重新构建.
>他们使用相同的.NET版本.
示例:如果将其添加到监视窗口MyDllType.SomeProperty,我将看到此消息(仅在监视窗口中):
“ MyDllType.SomeProperty”引发了类型为“ System.ArgumentException”的异常消息:“无法在对象实例上找到该方法.”
但是,如果要添加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添加到监视窗口时,我得到:
无法评估表达式.不支持该操作.未知错误: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;
}
您可能会想到,这真的很难调试我的应用程序:)任何帮助将不胜感激.
解决方法:
这不是一个答案,而是对监视窗口与调试打印输出之谜的一些见解.
Visual Studio中的“监视”窗口使用内置的托管表达式评估程序评估您的输入(例如structList).因此,作为运行时解析器,它是与编译器本身完全不同的野兽,并且仅理解表达式的子集.您可以阅读它的详细说明here.
因此,有可能-而且我似乎隐约记得自己曾经历过-该表达式求值器无法正确处理来自不安全DLL的类型.作为“轻量级编译器”,它确实确实存在一些缺点,这可能就是其中之一.
另一方面,Debug.WriteLine()可以正常工作,因为传递给它的表达式是在C#编译器本身的编译时进行处理的.