我想知道是否有人能指出我正确的方向我对 c# 还很陌生,所以请放轻松。
我的代码使用非托管 DLL,它是提供的用于与智能卡读卡器接口的 API,我无法控制 DLL,我只想将其包装在 c# 中以使其更易于使用。到目前为止,我已经设法做到了这一点,但我现在发现需要测试这个 DLL 的多个版本,这些版本的入口点相同,但参数可能不同。
我尝试了一些类似的方法来组织我的包装类;
internal static class UnSafeNativeMethods
{
internal static class READER
{
internal static class SDK20
{
[DllImport(dllpath, EntryPoint = "CV_SetCommunicationType")]
internal static extern int CV_SetCommunicationType(byte type);
...
}
internal static class SDK21
{
[DllImport(dllpath, EntryPoint = "CV_SetCommunicationType")]
internal static extern int CV_SetCommunicationType(byte type);
...
}
}
}
但是在检查要使用的调用时,它会产生非常难看的代码;
ReaderSDK sdk = ReaderSDK.SDK20 //Could come from a argument passed in or set in an
//instantiated class
...
switch (sdk)
{
case ReaderSDK.SDK20:
UnSafeNativeMethods.READER.SDK20.CV_SetCommunicationType(0x0);
break;
case ReaderSDK.SDK21:
UnSafeNativeMethods.READER.SDK21.CV_SetCommunicationType(0x0);
break;
...
}
这对我来说似乎很乱,想知道是否有人能指出我正确的方向......
编辑:离开下面的评论,我想出了一些示例代码,仍然不确定我是否在正确的轨道上,因为我的开关仍然存在,但它现在是混凝土工厂类的一部分。
public enum ConnectionType
{
RS232 = 0x0,
USB = 0x1,
UDP = 0x2
}
interface INativeMethods
{
string Name();
void SetCommunicationType(ConnectionType type);
}
class SDK20 : INativeMethods
{
public string Name()
{
return "SDK Version 2.0";
}
// Thanks to @dzendras for this!!
public void SetCommunicationType(ConnectionType type)
{
int result = UnSafeNativeMethods.READER.SDK20.CV_SetCommunicationType((byte)type);
switch (result)
{
case 0:
return;
case 1:
throw new NotSupportedException("Communication type not supported");
case 2:
throw AnyOtherMeaningfulException("Its message");
}
}
}
class SDK21 : INativeMethods
{
public string Name()
{
return "SDK Version 2.1";
}
// Thanks to @dzendras for this!!
public void SetCommunicationType(ConnectionType type)
{
int result = UnSafeNativeMethods.READER.SDK21.CV_SetCommunicationType((byte)type);
switch (result)
{
case 0:
return;
case 1:
throw new NotSupportedException("Communication type not supported");
case 2:
throw AnyOtherMeaningfulException("Its message");
}
}
}
class NativeMethodsFactory
{
private static NativeMethodsFactory instance = new NativeMethodsFactory();
private NativeMethodsFactory()
{
}
public static NativeMethodsFactory Instance
{
get { return NativeMethodsFactory.instance; }
}
public INativeMethods Get(ReaderSDK version)
{
switch (version)
{
case ReaderSDK.SDK20:
return new SDK20();
case ReaderSDK.SDK21:
return new SDK21();
default:
return new SDK20();
}
}
}
我在正确的轨道上吗?
这就是我现在实现对 SDK 的调用的方式......
// sdk passed in as enum, NativeMethods stored as class member.
NativeMethods = NativeMethodsFactory.Instance.Get(sdk);
...
NativeMethods.SetCommunicationType(ConnectionType.USB);