[转]使用C#调用金诚信71x系列读卡器的DLL
2008-01-28 11:41
363 查看
本文转自:http://blog.csdn.net/cnhyong/archive/2008/01/24/2064167.aspx
原文如下:
由于项目需要,我必须使用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 System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace QL.Card
{
public class Card
{
#region Win API 声明调用kernel.dll中的三个方法
[DllImport("kernel32.dll")]
private extern static IntPtr LoadLibrary(string path);
[DllImport("kernel32.dll")]
private extern static IntPtr GetProcAddress(IntPtr lib, string funcName);
[DllImport("kernel32.dll")]
private extern static bool FreeLibrary(IntPtr lib);
[DllImport("kernel32.dll")]
public static extern IntPtr GetStdHandle(int nStdHandle);
const int STD_OUTPUT_HANDLE = -11;
#endregion
private IntPtr hLib;
private IntPtr otherlib1;
private IntPtr otherlib2;
public (String DLLPath)
{
otherlib1 = LoadLibrary("MFC42D.dll");
otherlib2 = LoadLibrary("MSVCRTD.dll");
hLib = LoadLibrary(DLLPath); }
~DllInvoke()
{
FreeLibrary(hLib);
FreeLibrary(otherlib2);
FreeLibrary(otherlib1);
}
//将要执行的函数转换为委托
public Delegate Invoke (string APIName,Type t)
{
IntPtr api = GetProcAddress(hLib, APIName);
return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);
}
//这里将DLL里要调用的函数声明为委托,其中int为该函数的返回值
public delegate int readcard(//参数列表);
public delegate int writecard(//参数列表);
public string Read()
{
Carder dll = new Carder(Environment.CurrentDirectory + "\\ghc715.dll");
string mdata1 = "";
string mdata2 = "";
string error = "";
readcard rc = (readcard)dll.Invoke("readcard", typeof(readcard));
int rcCode = rc(1, 2, out mdata1, out mdata2, 2);
//接下来是一些错误处理
}
public string Write(string input)
{
Carder dll = new Carder(Environment.CurrentDirectory + "ghc715.dll");
string mdata1 = input;
string mdata2 = "";
string error = "";
writecard rc = (writecard)dll.Invoke("writecard", typeof(writecard));
int rcCode = rc(1, 2, mdata1,mdata2, 2);
//错误处理
}
}
}
就这么多了,希望大家多多指教!
原文如下:
由于项目需要,我必须使用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 System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace QL.Card
{
public class Card
{
#region Win API 声明调用kernel.dll中的三个方法
[DllImport("kernel32.dll")]
private extern static IntPtr LoadLibrary(string path);
[DllImport("kernel32.dll")]
private extern static IntPtr GetProcAddress(IntPtr lib, string funcName);
[DllImport("kernel32.dll")]
private extern static bool FreeLibrary(IntPtr lib);
[DllImport("kernel32.dll")]
public static extern IntPtr GetStdHandle(int nStdHandle);
const int STD_OUTPUT_HANDLE = -11;
#endregion
private IntPtr hLib;
private IntPtr otherlib1;
private IntPtr otherlib2;
public (String DLLPath)
{
otherlib1 = LoadLibrary("MFC42D.dll");
otherlib2 = LoadLibrary("MSVCRTD.dll");
hLib = LoadLibrary(DLLPath); }
~DllInvoke()
{
FreeLibrary(hLib);
FreeLibrary(otherlib2);
FreeLibrary(otherlib1);
}
//将要执行的函数转换为委托
public Delegate Invoke (string APIName,Type t)
{
IntPtr api = GetProcAddress(hLib, APIName);
return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);
}
//这里将DLL里要调用的函数声明为委托,其中int为该函数的返回值
public delegate int readcard(//参数列表);
public delegate int writecard(//参数列表);
public string Read()
{
Carder dll = new Carder(Environment.CurrentDirectory + "\\ghc715.dll");
string mdata1 = "";
string mdata2 = "";
string error = "";
readcard rc = (readcard)dll.Invoke("readcard", typeof(readcard));
int rcCode = rc(1, 2, out mdata1, out mdata2, 2);
//接下来是一些错误处理
}
public string Write(string input)
{
Carder dll = new Carder(Environment.CurrentDirectory + "ghc715.dll");
string mdata1 = input;
string mdata2 = "";
string error = "";
writecard rc = (writecard)dll.Invoke("writecard", typeof(writecard));
int rcCode = rc(1, 2, mdata1,mdata2, 2);
//错误处理
}
}
}
就这么多了,希望大家多多指教!
相关文章推荐
- [转]使用C#调用金诚信71x系列读卡器的DLL
- 使用C#调用金诚信71x系列读卡器的DLL
- 使用C#调用金诚信71x系列读卡器的DLL
- C#调用C++DLL 使用 德卡 读卡器 获取身份证信息
- 在VS2010上使用C#调用非托管C++生成opencv代码的DLL文件
- Windows平台下使用CodeBlocks+GCC编译器生成动态dll,C#调用报错
- 使用C++调用C#的DLL(转载)
- C#使用技巧--调用DLL
- 使用C#制作简单dll文件,并测试调用
- [JNA系列]Java调用Delphi编写的Dll之实例Delphi使用PAnsiChar
- C++工程代码打包的dll在C#工程上使用注意点!变量对应关系与dll调用出错情况。
- c#调用java代码(jar转化成dll):ikvm 使用注意事项
- C#调用使用C++\CLI封装的标准C++ DLL问题:无法访问受保护的内存,这通常指示其他内存已损坏
- C#编译器优化那点事 c# 如果一个对象的值为null,那么它调用扩展方法时为甚么不报错 webAPI 控制器(Controller)太多怎么办? .NET MVC项目设置包含Areas中的页面为默认启动页 (五)Net Core使用静态文件 学习ASP.NET Core Razor 编程系列八——并发处理
- SQL调用C# dll(第一中DLL,没使用强名称密匙,默认是 safe)
- InstallShield系列(二) 调用C#生成的dll
- 使用clr 调用C#编写的dll中的方法的全解释
- C#调用MySQL数据库(使用MySql.Data.dll连接)
- [JNA系列]Java调用Delphi编写的Dll之实例Delphi使用PWideChar
- C#使用技巧--调用DLL