2009-08-14 44 views
2

由于装配有一个入口点,如:[net]如何将调试代码注入程序集?

int FooClass::doFoo(int x, double y) 
{ 
    int ret; 
    // Do some foo 
    return ret; 
} 

是否有可能又使用另一个组件模拟像:

int FooClass::doFoo(int x, double y) 
{ 
    int ret; 
    TRACE_PARAM_INT(x) 
    TRACE_PARAM_DOUBLE(y) 
    // Do some foo 
    TRACE_RETURN_INT(ret) 
    return ret; 
} 

而且只启用此代码注入时DEBUG存在。如果有这种方式,你如何加载“调试”程序集?

编辑1:#ifdef不是一个选项。说,我不想修改代码库。

编辑2:我的主要问题是“如何将代码注入已编译的程序集”。我有基本代码,但我宁愿不在主代码中添加用于跟踪的K行,但有另一个程序集可以这样做。我知道如何使用VS进行调试,我想要的是添加变量的跟踪机制(除其他外)。

+0

您是说因为任何原因您不能触摸原始程序集? – Jared314 2009-08-17 22:46:24

回答

10

您可以尝试一个AOP后编译器,如PostSharp。它适用于所有.net语言,但我没有用C++试过。

+0

同意,我用企业库日志块postharp,记录参数传递给一个方法,它运作良好(c#) – Neil 2009-08-17 14:07:57

-2

取决于您是否有程序集的源代码以及是否可以重新编译它以允许调试。

假设您有源代码,并且您可以在启用调试的情况下对其进行编译,那么您应该可以使用开发人员工具(Visual Studio,我猜测)单步执行代码并查看值X,Y和ret,当你走。

这不会要求修改代码 - 只是编译调试版本的能力。

3

为了将代码注入到现有程序集中,我将使用Cecil库,该库可让您使用IL。这会让你重写程序集,如果这就是你想要的。我必须警告你:这是不小的壮举。

哦,还有一个Reflector的加载项,称为Reflexil,它允许您编辑程序集。

顺便说一下,基于AOP的跟踪不会将代码直接添加到您的程序集。你可以将所有AOP的东西保存在一个单独的程序集中(实际上,这是一个非常好的主意),然后将其应用于属性。 PostSharp将为您编写代码,但其他AOP框架(如Spring或PIAB)使用动态代理时使事情更加灵活,因此您可以在不需要时有效地“关闭”您的方面。

2

The Enterprise Library Policy Injection Application Block允许您在方法调用之间执行代码。它不会做你在问题中要求的复杂的东西,它涉及在代码中注入代码,但它可能已经足够满足你的需求,并且它是免费的。

+0

这实际上可以满足我的需求。我并不需要向方法的主体注入代码,但需要跟踪方法调用和返回语句。 – Anzurio 2009-08-19 01:19:23

0

如果doFoo函数不是虚拟的,或者如果不通过接口访问该类,则不能这样做。

原因是,当你正在编译使用doFoo的类被编译来调用确切的类的确切功能。因此,在编译时评估接收调用的目标类。 但是,如果该函数是虚拟的,或者通过接口访问类,则将在运行时评估接收调用的目标类。因此,为了使用任何AOP(面向方面​​编程)或DI(直接注入)框架来完成你想要的任务,目标类需要满足这些条件之一。通常通过接口访问类将是首选方式。

这里有很多不同的AOP和DI框架,但帖子并不是关于哪一个使用的,所以我会让自己不这样做,但是如果你不需要这样的话,你可以使用DynamicProxy创建装饰器以添加日志记录功能,包括界面和具有虚拟功能的类。后者创建了一个新类,它是您已经拥有的一个子类