C#調用Delphi DLL獲取字符串(C# IntPtr 與 string互轉 )


前因后果

調用一門鎖的dll實現讀取酒店IC卡數據,直接用Readme里的方法出錯。

函數聲明:

一、讀卡函數
    ************************ Delphi 調用 *************************
    * function DLL_Read:PChar;
               external 'AnLock_2012.dll'; stdcall;
    **************************************************************
    *
    ************************* VB 調用 ****************************
    * Private Declare Function DLL_Read Lib "AnLock_2012.dll" As String
    *
    **************************************************************
    *
    ************************* PB 調用 ****************************
    * Function String DLL_Read Library "AnLock_2012.dll";
    **************************************************************
    *
    ************************* C# 調用 ****************************
    * [DllImport("AnLock_2012.dll", EntryPoint = "DLL_Read", CharSet = CharSet.None, SetLastError = false)]
    *    public static extern String DLL_Read;
    **************************************************************
    **************************************************************
 返回字符串格式說明:
 |CardNo     卡號
 |CardType   卡片類型
 |Building   樓棟號
 |Floor      樓層號
 |RC         鎖內號(門鎖內定義的房間編號,與房間號一一對應)
 |RN         房間號(若無關聯房間號,則為鎖內號)
 |StartDT    入住時間
 |EndDT      欲離時間
 |OpenUnLock 可開反鎖
 |AlwaysOpen 常開門
 |EndOldCard 終止前卡
    **************************************************************

    讀卡返回值例子
    例1: |CardNo3354970509|CardTypeGuestCard|RC1101|RN1101|StartDT20131209_00:00|EndDT20131214_00:00
         以上讀卡信息表示:
         卡號為3354970509,卡片類型為GuestCard(賓客卡)
         |RC1101|RN1101當不在門鎖系統內鎖內號與房號相等,一般只需處理|RC1101(鎖內號)
         |StartDT20131209_00:00|EndDT20131214_00:00 表示入住時間為2013年12月09號0點、退房時間2013年12月14號0點

 

[DllImport("ANLOCK_2012.dll", EntryPoint = "DLL_Read", CharSet = CharSet.None, SetLastError = false)]
        public static extern string DLL_Read();

  

分析和解決辦法

delphi里導出string估計是使用的pchar,那么C#里面調用時取到是內存地址的句柄才對,試試用IntPtr來接收。一測試OK了。其實問題就是一句話:C# IntPtr與string的互轉。

另外64位操作系統也會報錯,解決辦法就是編譯生成的時候不要用AnyCPU,用x86。

正確的姿勢:

        [DllImport("ANLOCK_2012.dll", EntryPoint = "DLL_Read", CharSet = CharSet.None, SetLastError = false)]
        public static extern IntPtr DLL_Read();

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        { 
            var temp = DLL_Read();
            string ss = Marshal.PtrToStringAnsi(temp);
            textBox1.Text = ss;
            //最后釋放掉
            //Marshal.FreeHGlobal(temp);
        }

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM