程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 使用C#調用金誠信71x系列讀卡器的DLL

使用C#調用金誠信71x系列讀卡器的DLL

編輯:.NET實例教程

        由於項目需要,我必須使用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
    {

$False$

        #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(ot

herlib1);
        }

        //將要執行的函數轉換為委托
        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");
          &n

bsp; string mdata1 = input;
            string mdata2 = "";
            string error = "";
            writecard rc = (writecard)dll.Invoke("writecard", typeof(writecard));

            int rcCode = rc(1, 2, mdata1,mdata2, 2);

            //錯誤處理
            
         }

    }
}

就這麼多了,希望大家多多指教!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved