我以依时利读卡器会例说一说,其它类似.
1.先把含有接口类库的DLL文件拷到:c:\windows\system32下.
2. [DllImport("EastRiver.dll", SetLastError = true, CharSet = CharSet.Ansi, EntryPoint = "BatchReadRecord")]
public static extern int BatchReadRecord(int port,StringBuilder record,int size);
每一个方法都需要这样注册一样.根据需要改写.但是类型需要注意一下.下面是对照表.
Win32 Types |
Specification |
CLR Type |
char, INT8, SBYTE, CHAR†|
8-bit signed integer |
System.SByte |
short, short int, INT16, SHORT |
16-bit signed integer |
System.Int16 |
int, long, long int, INT32, LONG32, BOOL†, INT |
32-bit signed integer |
System.Int32 |
__int64, INT64, LONGLONG |
64-bit signed integer |
System.Int64 |
unsigned char, UINT8, UCHAR†, BYTE |
8-bit unsigned integer |
System.Byte |
unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR†, __wchar_t |
16-bit unsigned integer |
System.UInt16 |
unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT |
32-bit unsigned integer |
System.UInt32 |
unsigned __int64, UINT64, DWORDLONG, ULONGLONG |
64-bit unsigned integer |
System.UInt64 |
float, FLOAT |
Single-precision floating point |
System.Single |
double, long double, DOUBLE |
Double-precision floating point |
System.Double |
†In Win32 this type is an integer with a specially assigned meaning; in contrast, the CLR provides a specific type |
我是建一个BaseForm基类,然后所有的窗体都继承就可以了.这样省得都写了,呵呵.
3.string类型的需要创建固定长度的.所以我选择的StringBuilder.网上有哥们说用intPtr,这个哥们不太懂.所以先这样了.但是存在如果返回的是Array类型的时候可能不能够完全读出内容的问题.用VB的代码可以这样.Dim data As string * 1100,可以完全读出,但是sb好像不太可以.我只能读出卡号,后在的内容不能读出来,我现在只需要卡号,所以先这样了,有知道的朋友可以告诉一声.
更深入的可以参考:微软MSDN上的《在 C# 中通过 P/Invoke 调用Win32 DLL》。
小总结一下:
1. 在使用DllImport将Win32函数导入成C#对应的函数时,一定要注意Win32函数中的参数是传入还是传出,是值类型还是引用类型;
2. 对于C/C++中的复杂类型如Struct,转成C#对应的数据结构时,最好使用C#的Class而不是值类型的Struct;
3. 对于C/C++中的指针类型,最好使用IntPtr类型来进行数据的封送处理; (这个至今没弄太明白)
4. .NET的字符串在内存中总是以Unicode方式编码的,但对于API函数需要string的编码,有时取决于Windows版本,有时需要显式设定,有时又需要显式转换。
5. 使用与基础 API 函数类型不同但与之兼容的 CLR 类型是 P/Invoke 较难使用的一个方面,这就需要多多实践,积累经验。