您的位置:首页 > 编程语言 > C#

使用C#调用金诚信71x系列读卡器的DLL

2008-09-23 09:07 465 查看
由于项目需要,我必须使用C#来操作读卡器,读卡器只提供了几个可供调用的DLL文件,并没呀给出例程之类的资源,虽然我认为这个读卡器厂商非常失败,但是我也只能耐着性子做完这件事情。

我们在使用C++的时候,对动态链接库的操作是非常方便的,只要使用LoadLibrary()就可以很简单的调用该DLL文件中所包含的函数。但是使用.NET 2.0就不那么容易了,由于本人使用C#,所以以C#代码为例与大家共享如何在.NET平台下对DLL文件进行调用。

1.使用DLL函数查看器对读卡器厂商提供的DLL文件进行了分析。找出了函数名,和DLL的依赖关系。DLL的依赖关系非常重要,我们必须找到ghc715.dll依赖的DLL文件,并且在加载动态链接库的时候必须先将依赖的DLL加载到系统中,才能保证我们对读卡器可以进行操作。

2.using System.Runtime.InteropServices;该命名空间提供各种各样支持 COM interop 及平台调用服务的成员。主要是用于与非托管代码之间的交互。该命名空间中=最重要的属性有 DllImportAttribute(可以用来定义用于访问非托管 API 的平台调用方法)和 MarshalAsAttribute(可以用来指定如何在托管内存与非托管内存之间封送数据)。 详见http://msdn2.microsoft.com/zh-cn/library/system.runtime.interopservices(VS.80).aspx

3.由于读卡器提供的DLL文件无法在系统内注册,所以我们只能采用动态加载的方法来完成这一工作。使用了如下几个Windows 的 API:

1. Loadlibrary: 装载指定DLL动态库
2. GetProcAddress:获得函数的入口地址
3. Freelibrary: 从内存中卸载动态库

为了完成调用GetProcAddress返回的函数地址,我们使用了Marshal.GetDelegateForFunctionPointer方法,该方法将非托管函数的指针转换为委托。

看到这些知识,剩下的事情就简单了,我把所有对读卡器的操作封装成了一个类,提供两个public 函数,一个是Read(读卡)另外一个就是Write(写卡)。并把类的主要结构写到下面,仅供参考,希望有高人给出一些指点意见。


复制

保存
using[/b] System;
using[/b] System.Collections.Generic;
using[/b] System.Text;
using[/b] System.Runtime.InteropServices;

namespace[/b] QL.Card
{
public[/b] class[/b] Card
{

#region Win API 声明调用kernel.dll中的三个方法
[/b]        [DllImport("kernel32.dll"[/b])]
private[/b] extern[/b] static[/b] IntPtr LoadLibrary(string[/b] path);

[DllImport("kernel32.dll"[/b])]
private[/b] extern[/b] static[/b] IntPtr GetProcAddress(IntPtr lib, string[/b] funcName);

[DllImport("kernel32.dll"[/b])]
private[/b] extern[/b] static[/b] bool[/b] FreeLibrary(IntPtr lib);

[DllImport("kernel32.dll"[/b])]
public[/b] static[/b] extern[/b] IntPtr GetStdHandle(int[/b] nStdHandle);
const[/b] int[/b] STD_OUTPUT_HANDLE = -11;

#endregion
[/b]
private[/b] IntPtr hLib;
private[/b] IntPtr otherlib1;
private[/b] IntPtr otherlib2;

public[/b] Card(String DLLPath)
{
otherlib1 = LoadLibrary("MFC42D.dll"[/b]);
otherlib2 = LoadLibrary("MSVCRTD.dll"[/b]);
hLib = LoadLibrary(DLLPath);        }

~Card()
{
FreeLibrary(hLib);
FreeLibrary(otherlib2);
FreeLibrary(otherlib1);
}

//将要执行的函数转换为委托
[/b]        public[/b] Delegate Invoke (string[/b] APIName,Type t)
{
IntPtr api = GetProcAddress(hLib, APIName);
return[/b] (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);
}

//这里将DLL里要调用的函数声明为委托,其中int为该函数的返回值
[/b]
public[/b] delegate[/b] int[/b] readcard(string[/b] str//参数列表);

public[/b] delegate[/b] int[/b] writecard(string[/b] str//参数列表);

public[/b] string[/b] Read()
{
Carder dll = new[/b] Carder(Environment.CurrentDirectory + "//ghc715.dll"[/b]);
string[/b] mdata1 = ""[/b];
string[/b] mdata2 = ""[/b];
string[/b] error = ""[/b];
readcard rc = (readcard)dll.Invoke("readcard"[/b], typeof[/b](readcard));

int[/b] rcCode = rc(1, 2, out[/b] mdata1, out[/b] mdata2, 2);

//接下来是一些错误处理
[/b]
}
public[/b]  string[/b] Write(string[/b] input)
{
Carder dll = new[/b] Carder(Environment.CurrentDirectory + "ghc715.dll"[/b]);
string[/b] mdata1 = input;
string[/b] mdata2 = ""[/b];
string[/b] error = ""[/b];
writecard rc = (writecard)dll.Invoke("writecard"[/b], typeof[/b](writecard));

int[/b] rcCode = rc(1, 2, mdata1,mdata2, 2);

//错误处理
[/b]         }
}
}

就这么多了,希望大家多多指教!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐