我需要从包含一个C#WinForms项目的解决方案中引用EmguCV。
同一个库有四个版本,即x86 vand 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]
的值以编程方式在版本之间切换?
答案 0 :(得分:1)
步骤1:为EmguCv
中正在使用的对象创建界面,并将它们放在单独的AnyCpu
项目中。如果这些对象没有公共接口,或者当您无法更改这些对象时,则需要为这些类创建自己的包装器对象。这些接口在它们自己的程序集中定义非常重要,因为您将从所有自己的代码中引用此程序集。
public interface IEmguCv{ /* methods and proeprties */ }
public class EmguCv : IEmguCv { }
现在在您现有的应用程序中,使用Reflection或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接口,它将为您提供强大的绑定,IntelliSense以及您期望的所有其他功能,但您将能够根据您所处的上下文动态加载程序集。
如果你需要在EmguCv对象上调用非默认构造函数,那么你可以使用Activator.CreateInstance(Type, Object[], Object[])
重载,或者通过Type.GetConstructor(Type[]).Invoke()
调用构造函数。
一旦定义了界面,您也可以使用Unity或NInject等库,这样您就可以使用这些DI容器为您进行反射工作。