我需要从包含一个c# WinForms项目的解决方案中引用EmguCV。
相同的库有四个版本,即x86和x64,每个都有或没有GPU支持。该库需要引用EmguCV的托管dll以及OpenCV的非托管dll。通过构建后事件将正确的非托管版本复制到[Bin]
文件夹很容易。
我希望能够通过代码轻松地在托管引用之间切换。也许像下面这样:
public enum EnumEmguCvTarget
{
None, // Do not use EmguCv
EmguCvTargetTbb86, // Target EmguCv for x86 without GPU.
EmguCvTargetGpu86, // Target EmguCv for x86 with GPU.
EmguCvTargetTbb64, // Target EmguCv for x64 without GPU.
EmguCvTargetGpu64, // Target EmguCv for x64 with GPU.
}
public EnumEmguCvTarget EmguCvTarget
{ get { return (EnumEmguCvTarget.EmguCvTargetGpu64); } }
由于我在编译时引用这些程序集(而不是后期绑定),是否有一种方法可以基于[EmguCvTarget]
的值在版本之间编程切换?
步骤1:为您在EmguCv
中使用的对象创建接口,并将其放置在单独的AnyCpu
项目中。如果这些对象没有公共接口,或者无法更改这些对象,则需要为这些类创建自己的包装器对象。重要的是,这些接口在它们自己的程序集中定义,因为您将从自己的所有代码中引用该程序集。
public interface IEmguCv{ /* methods and proeprties */ }
public class EmguCv : IEmguCv { }
现在,在您现有的应用程序中,使用反射或Activator.CreateInstance
来加载正确的程序集:
// which assembly to load depends on your configuration
Assembly emguAssembly = Assembly.Load("EmguX64");
Type emguType = emguAssembly.GetType("EmguCvClassYouAddedInterfacesTo");
IEmguCv object = (IEmguCv)Activator.CreateInstance(emguType);
从这里你可以使用IEmguCv接口,它将为你提供强绑定、智能感知和所有你期望的其他东西,但你将能够根据你所处的上下文动态加载程序集。
如果你需要调用EmguCv对象的非默认构造函数,那么你可以使用Activator.CreateInstance(Type, Object[], Object[])
重载,或者通过Type.GetConstructor(Type[]).Invoke()
调用构造函数。
一旦你定义了一个接口,你也可以使用像Unity或NInject这样的库,这样你就可以使用这些DI容器为你做反射工作。