关于C#调用API的理解(汇多考勤机HD4K)

很多时候为了做集成我们别无选择的要用C#来调用C/C++的API,如果你对C#和C/C++数据类型对应关系不是很了解,那么这就是一件很头疼的事情了。

下面来看看具体怎么使用

void* OpenDevice(int nMyAddress, HWND hWnd)
void CloseDevice(void* pDevice)
void SetMyAddress(void* pDevice, int nAddress) 
BOOL ConnectPort(
void* pDevice, LPCTSTR lpCommDef)
BOOL IsConnect(
void* pDevice)
void SetAddLog(void* pDevice, BOOL bAddLog)
void SetCommKey(void* pDevice, LPCTSTR lpCommKey)
void SetInnerCode (void* pDevice, BOOL bBig5)
BOOL DisConnectPort(
void* pDevice)
void SetWaitTime(void* pDevice, DWORD dwWaitTime)
void* StartICDMCommand(void* pDevice, int nAddress, int nCommand, 
void* pParameters = NULL, int nSizeOfParameter = 0)
int GetSizeOfData(void* pCommand)
BOOL GetData(
void* pCommand, void* pDataBuffer, int nSize)
int GetCmdResult(void* pCommand)
void EndICDMCommand(void* pCommand)
void RecvEdition(LPTSTR lpEdition)

上面是api接口原函数

如果想要在C#里面使用就要重新定义以为他是非托管类行

[DllImport("DLL4k.dll", ExactSpelling = false, EntryPoint = "OpenDevice")]
public static extern IntPtr OpenDevice(int nMyAddress, IntPtr hwnd);
[DllImport(
"DLL4k.dll", SetLastError = true, EntryPoint = "CloseDevice")]
public static extern void CloseDevice(IntPtr hwnd);
[DllImport(
"DLL4k.dll", SetLastError = true)]
public static extern void SetMyAddress(IntPtr hwnd, int nMyAddress);
[DllImport(
"DLL4k.dll", ExactSpelling = false, EntryPoint = "ConnectPort")]
public static extern bool ConnectPort(IntPtr pDevice, StringBuilder port);  
[DllImport(
"DLL4k.dll", SetLastError = true, EntryPoint = "IsConnect")]
[
return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
public static extern bool IsConnect(IntPtr pDevice);
[DllImport(
"DLL4k.dll", SetLastError = true, EntryPoint = "SetAddLog")]
public static extern void SetAddLog(IntPtr pDevice, bool isaddlog);
[DllImport(
"DLL4k.dll", SetLastError = true)]
public static extern void SetCommKey(IntPtr pDevice, string str);
[DllImport(
"DLL4k.dll", SetLastError = true)]
public static extern void SetInnerCode(IntPtr pDevice, bool isbog5);
[DllImport(
"DLL4k.dll", SetLastError = true, EntryPoint = "DisConnectPort")]
[
return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
public static extern bool DisConnectPort(IntPtr pDevice);
[DllImport(
"DLL4k.dll", SetLastError = true, EntryPoint = "SetWaitTime")]
public static extern void SetWaitTime(IntPtr pDevice, int dwWaitTime);
[DllImport(
"DLL4k.dll", ExactSpelling = false, EntryPoint = "StartICDMCommand")]
public static extern IntPtr StartICDMCommand(IntPtr pDevice, int nAddress, int nCommand, IntPtr pParameters, int nSizeOfParameter = 0);
[DllImport(
"DLL4k.dll", EntryPoint = "GetSizeOfData", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int GetSizeOfData(IntPtr pParameters);
[DllImport(
"DLL4k.dll", EntryPoint = "GetData", SetLastError = true)]
[
return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
public static extern bool GetData(IntPtr pCommand, IntPtr pDataBuffer, int nSize);
[DllImport(
"DLL4k.dll", SetLastError = true, EntryPoint = "GetCmdResult")]
public static extern int GetCmdResult(IntPtr pCommand);
[DllImport(
"DLL4k.dll", SetLastError = true, EntryPoint = "EndICDMCommand")]
public static extern void EndICDMCommand(IntPtr pDevice);
[DllImport(
"DLL4k.dll", SetLastError = true)]
public static extern void RecvEdition(string str);

以上就是c#调用函数一定要是静态的

下面来看看一个列子

public IntPtr hwnd;
StringBuilder sb 
= new StringBuilder();
public static IntPtr showhwnd = System.Diagnostics.Process.GetCurrentProcess().Handle;
public static IntPtr api = OpenDevice(0, showhwnd);
public IntPtr kk = new IntPtr();
public static int rcount = 0;

以上要是全局变量

最后是下载数据的调用例子

sb.Clear();
sb.AppendFormat(
"{0}:baud={1},parity=N,data=8,stop=1", cbPort.Text, cbRate.Text);
int count = 0;
if (!IsConnect(api))
{
    
bool islink = ConnectPort(api, sb);
    DMSTATUS dmm 
= new DMSTATUS();
    
int sizenewb = Marshal.SizeOf(dmm);
    IntPtr buffernew 
= Marshal.AllocCoTaskMem(sizenewb);
    
int sizenewa = 0;
    
try
    {
    
//将托管对象拷贝到非托管内存
    SetWaitTime(api, 3000);
    Marshal.StructureToPtr(dmm, buffernew, 
true);
    SetAddLog(api, 
true);
        kk 
= StartICDMCommand(api, 0, (int)CMDWORD.nRecvDMStatus, buffernew, sizenewb);
        rcount 
= GetCmdResult(kk);
        
if (rcount != 0)
        {
            sizenewa 
= GetSizeOfData(kk);
            
bool isok = GetData(kk, buffernew, sizenewa);
            DMSTATUS mm 
= (DMSTATUS)Marshal.PtrToStructure(buffernew, typeof(DMSTATUS));
            count 
= mm.nRecordCount;
            EndICDMCommand(kk);
            StringBuilder sbt 
= new StringBuilder();
            
int totalcount = 0;
            
if (count % 100 == 0)
            {
            totalcount 
= count / 100;
            }
            
else
            {
               totalcount 
= (count / 100+ 1;
            }
            
for (int i = 0; i < totalcount; i++)
            {
               
bool link = ConnectPort(api, sb);
               
if (link)
               {
                  ATTGUARDRECORD[] Record 
= new ATTGUARDRECORD[100];
                  
int sizerecord = Marshal.SizeOf(Record[0]);
                  IntPtr bufferrecord 
= Marshal.AllocCoTaskMem(sizerecord * 100);
                  kk 
= StartICDMCommand(api, 0, (int)CMDWORD.nRecvDelRecord, bufferrecord, sizerecord);
                  rcount 
= GetCmdResult(kk);
                  
if (rcount > 0)
                  {
                     
int sizecount = GetSizeOfData(kk);
                     GetData(kk, bufferrecord, sizecount);
                     
for (int j = 0; j < 100; j++)
                     {
                     Record[j] 
= (ATTGUARDRECORD)Marshal.PtrToStructure((IntPtr)(bufferrecord + sizerecord * j), typeof(ATTGUARDRECORD));
                     
if (Record[j].nYear > 0)
                     {
                       sbt.AppendLine(Record[j].strPersonID 
+ "-" +Record[j].nYear.ToString() + "-" + Record[j].nMonth.ToString() + "-" + Record[j].nDay.ToString() + "-"+ Record[j].nHour.ToString() + ":" + Record[j].nMinute.ToString()+ ":" + Record[j].nSecond.ToString()+ "-" +Record[j].bOnDuty.ToString() + "-" + Record[j].bBC.ToString() + "-" + Record[j].nDMAdr);
                                }
                                
else
                                {
                                    
continue;
                                }
                        }
                        IntPtr del 
= new IntPtr();
                        StartICDMCommand(api, 
0, (int)CMDWORD.nRecvDelRecordRlt, del);
                        }
                    }
                    EndICDMCommand(kk);
            }
            txtcontent.Text 
= sbt.ToString();
            }
        }
        
catch
        {

        }

} 

这样就结束了

原文地址:https://www.cnblogs.com/keepsilence/p/2182373.html