声明:
简述:
目录:
1.调用Dll
2.如何调用C++ Dll接口
Dll接口定义格式简述:
C++ : extern + 返回类型 + _stdcall + 函数名称(参数定义);
C# : [Dllmport("接口所在Dll",SetLastError = true)]
public static extern +返回类型 + 函数名称(参数定义);
确定Dll中提供的接口部分,举例我使用的服务端提供的Dll名称为:CMS_ClientComm.dll,那么我调用此Dll中一个接口:CMS_Init()
C++ :extern int __stdcall CMS_Init();
C#: [DllImport("CMS_ClientComm.dll", SetLastError = true)]
public static extern int CMS_Init();
3.C++数据类型与C#数据类型对照表
C++ | c# |
int | int |
unsigned int | uint |
bool | byte |
float | float |
OUT float& | ref float |
OUT int& | ref int |
long* | long[] |
Out char* | ref string |
OUT char * | byte[] |
char* | byte[] |
void* | IntPtr |
__int64 | long |
unsigned short | ushort |
3.C++结构体类型与C#结构体类型对照表
类型1:正常使用结构体
C++:
struct CMS_LOCAL_RECORD_SET
{
char szFilePath[256];
int iFileType;
int iTimeLen;
bool bAudio;
unsigned int uiReserved[4];
};
extern int __stdcall CMS_StartRecordLiveStreamAsFile(IN CAMERA_HANDLE hCamera,IN CMS_LOCAL_RECORD_SET set);
C#:
[StructLayout(LayoutKind.Sequential,Pack= 1)]
public struct CMS_LOCAL_RECORD_SET
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] szFilePath;
public int iFileType;
public int iTimeLen;
public byte bAudio;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public uint[] uiReserve;
};
[DllImport("CMS_ClientComm.dll", SetLastError = true)]
public static extern int CMS_StartRecordLiveStreamAsFile(IntPtr cameraHandle, CMS_LOCAL_RECORD_SET set);
类型2:(正常转换,只需注意数组转换时使用ByValArray,并注明数组大小。结构体参数其实为指针,对应的C#转换用引用类型)
C++:
typedef struct CMS_LogonData
{
char cSvrIP[64];
char cUser[64];
char cPwd[64];
}*LPCMS_LogonData;
C#:
[StructLayout(LayoutKind.Sequential)]
public struct CMS_LogonData
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] cSvrIP;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] cUser;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] cPwd;
};
此时接口中的调用:
C++:
extern void* __stdcall CMS_Logon(IN LPCMS_LogonData pData);
C#:(加ref引用标示)
[DllImport("CMS_ClientComm.dll", SetLastError = true)]
public static extern IntPtr CMS_Logon(ref CMS_LogonData logonData);
类型3:(有时需要加Pack = 1,否则会出现字符错位问题)
C++:
typedef struct CMS_NAME_FILE_RULE_SET
{
char szSuffix[10];
char szPrefix[40];
bool bIncludeCameraName;
bool bIncludeBeginTime;
unsigned int uiReserved[2];
}*PCMS_NAME_FILE_RULE_SET;
C#
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct CMS_NAME_FILE_RULE_SET
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] szSuffix;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public byte[] szPrefix;
public byte bIncludeCameraName;
public byte bIncludeBeginTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public uint[] uiReserved;
}
4.多级嵌套结构体转换
C++:
struct CMS_DATE
{
unsigned short wYear;
unsigned short wMonth;
unsigned short wDay;
};
struct CMS_TIME
{
unsigned short wHour;
unsigned short wMinute;
unsigned short wSecond;
};
typedef struct CMS_DeviceRecordPlan
{
void * hRecord;
char cType;
CMS_TIME cmsStartTime;
CMS_TIME cmsEndTime;
CMS_DATE cmsDate;
int nWeek[7];
char cName[48];
int nSyncAudio;
}*LPCMS_DeviceRecordPlan;
typedef struct CMS_RecordPlanRes
{
int unPlanNum;
CMS_DeviceRecordPlan sRecordPlan[1024];
}*LPCMS_RecordPlanRes;
extern int __stdcall CMS_GetRecordPlan(IN void* hCamera,OUT LPCMS_RecordPlanRes *pData);
C#:
[StructLayout(LayoutKind.Sequential)]
public struct CMS_TIME
{
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
};
[StructLayout(LayoutKind.Sequential)]
public struct CMS_DATE
{
public ushort wYear;
public ushort wMonth;
public ushort wDay;
};
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct CMS_DeviceRecordPlan
{
public IntPtr hRecord;
public byte cType;
public CMS_TIME cmsStartTime;
public CMS_TIME cmsEndTime;
public CMS_DATE cmsDate;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public int[] nWeek;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public byte[] cName;
public int nSyncAudio;
};
[StructLayout(LayoutKind.Sequential,Pack = 1)]
public struct CMS_RecordPlanRes
{
public int unPlanNum;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
public CMS_DeviceRecordPlan[] sRecordPlan;
};
[DllImport("CMS_ClientComm.dll", SetLastError = true)]
public static extern int CMS_GetRecordPlan(IntPtr cameraHandle, ref CMS_RecordPlanRes[] recordPlans);
5.回调函数转换
C++:
typedef struct CMS_MessageEx
{
void* hSer;
int nEventType;
char cDesc[260];
void* pContext;
long* pReserve;
long* pReserve1;
}*LPCMS_MessageEx;
typedef void (__stdcall *pfnRecvMsgEx)(LPCMS_MessageEx pLog);
extern int __stdcall CMS_SetCB_RecvMsgEx(IN SERVER_HANDLE hLID,IN pfnRecvMsgEx pLogFuncEx,IN void* pContext);
C#:
[StructLayout(LayoutKind.Sequential)]
public struct CMS_MessageEx
{
public IntPtr hSer;
public int nEventType;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 260)]
public byte[] cDesc;
public IntPtr pContext;
public IntPtr pReserve;
public IntPtr pReserve1;
};
public delegate void CallBackRecvMsgEx(ref CMS_MessageEx pLog);
[DllImport("CMS_ClientComm.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int CMS_SetCB_RecvMsgEx(IntPtr serverHandle, CallBackRecvMsgEx pLogFunc, IntPtr pContext);