这段时间用C++给客户做了一个通讯的dll。但客户是用C#的,所以研究了下C#,把C++的头文件,改写成C#的。主要是转换了结构体的定义,dll函数的调用,C#中的dll的动态调用,C++和C#之间的时间变量的传递。现在和大家分享一下。
C++的头文件:
#pragma once
//
//设置
//
typedef struct _RMusterSettings
{
DWORD dwDataSize;
RComm Comm;
RCoData CoData;
double RealClock;
WORD MeterCount;
WORD RecNoMax;
struct _RAutoReadSettings
{
BYTE Enable;
BYTE Days[31];
struct _RARTime
{
BYTE Enable;
BYTE Hour;
BYTE Min;
BYTE Sec;
}Time[24];
} RAutoReadSettings;
} RMusterSettings;
//
//通讯类定义
//
typedef HANDLE (*CREATEXXXXCOMM)();
typedef INT (*FREEXXXXCOMM)(HANDLE);
typedef INT (*XXXXCOMM)(HANDLE,WORD,void *);
typedef INT (*XXXXABORT)(HANDLE);
class CXXXXComm
{
private:
HINSTANCE hLib;
HANDLE hXXXXComm;
CREATEXXXXCOMM fnCreateXXXXComm;
FREEXXXXCOMM fnFreeXXXXComm;
XXXXCOMM fnXXXXComm;
XXXXABORT fnXXXXAbort;
public:
CXXXXComm(PCHAR fileName)
{
hLib = LoadLibrary(fileName);
if (hLib != NULL)
{
fnCreateXXXXComm = (CREATEXXXXCOMM) GetProcAddress(hLib, "CreateXXXXComm");
fnFreeXXXXComm = (FREEXXXXCOMM) GetProcAddress(hLib, "FreeXXXXComm");
fnXXXXComm = (XXXXCOMM) GetProcAddress(hLib, "XXXXComm");
fnXXXXAbort = (XXXXABORT) GetProcAddress(hLib, "XXXXAbort");
hXXXXComm = fnCreateXXXXComm();
}
};
~CXXXXComm()
{
if (hLib != NULL)
{
fnFreeXXXXComm(hXXXXComm);
FreeLibrary(hLib);
}
};
INT Comm(WORD cmd, void * data)
{
if (hLib != NULL)
return fnXXXXComm(hXXXXComm,cmd,data);
else
return EC_DLL_NOT_FOUND;
};
INT Abort()
{
if (hLib != NULL)
return fnXXXXAbort(hXXXXComm);
else
return 0;
};
};
C#的类文件
using System;
using System.Runtime.InteropServices;
namespace Flagele.rd.CXXXXComm
{
//
//设置
//
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct RARTime
{
public byte Enable;
public byte Hour;
public byte Min;
public byte Sec;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct RAutoReadSettings
{
public byte Enable;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 31)]
public byte[] Days;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
public RARTime[] Time;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class RMusterSettings
{
public uint dwDataSize;
public RComm Comm;
public RCoData CoData;
//
public long RealClock;
public ushort MeterCount;
public ushort RecNoMax;
public RAutoReadSettings ARSettings;
}
//
//通讯类
//
public class CXXXXComm
{
private uint hLib;
private uint hXXXXComm;
private delegate uint CREATEXXXXCOMM();
private delegate uint FREEXXXXCOMM(uint hFe);
private delegate uint XXXXCOMM(uint hFe, ushort cmd, [In,Out,MarshalAs(UnmanagedType.AsAny)] Object data);
private delegate uint XXXXABORT(uint hFe);
private CREATEXXXXCOMM fnCreateXXXXComm;
private FREEXXXXCOMM fnFreeXXXXComm;
private XXXXCOMM fnXXXXComm;
private XXXXABORT fnXXXXAbort;
[DllImport("Kernel32")]
private static extern uint GetProcAddress(uint handle, String funcname);
[DllImport("Kernel32")]
private static extern uint LoadLibrary(String funcname);
[DllImport("Kernel32")]
private static extern uint FreeLibrary(uint handle);
private static Delegate GetAddress(uint dllModule, string functionname, Type t)
{
uint addr = GetProcAddress(dllModule, functionname);
if (addr == 0)
return null;
else
return Marshal.GetDelegateForFunctionPointer(new IntPtr(addr), t);
}
public CXXXXComm()
{
hLib = LoadLibrary("XXXXComm.dll");
if (hLib != 0)
{
fnCreateXXXXComm = (CREATEXXXXCOMM)GetAddress(hLib, "CreateXXXXComm", typeof(CREATEXXXXCOMM));
fnFreeXXXXComm = (FREEXXXXCOMM)GetAddress(hLib, "FreeXXXXComm", typeof(FREEXXXXCOMM));
fnXXXXComm = (XXXXCOMM)GetAddress(hLib, "XXXXComm", typeof(XXXXCOMM));
fnXXXXAbort = (XXXXABORT)GetAddress(hLib, "XXXXAbort", typeof(XXXXABORT));
if (fnCreateXXXXComm != null)
{
hXXXXComm = fnCreateXXXXComm();
}
}
}
~CXXXXComm()
{
if (fnFreeXXXXComm != null)
{
fnFreeXXXXComm(hXXXXComm);
}
if (hLib != 0)
{
FreeLibrary(hLib);
}
}
public uint comm(ushort cmd, [MarshalAs(UnmanagedType.AsAny)] Object data)
{
if (hLib != 0)
{
return fnXXXXComm(hXXXXComm, cmd, data);
}
else
return CFeError.EC_DLL_NOT_FOUND;
}
public uint abort()
{
if (hLib != 0)
{
return fnXXXXAbort(hXXXXComm);
}
else
return 0;
}
}
}
C#的调用例子
//事先要创建XXXXComm
//private CXXXXComm XXXXComm;
//public Form1()
//{
// InitializeComponent();
// XXXXComm= new CXXXXComm();
//}
//
//▼写设置
//
mustersettings.ARSettings.Enable = 1;
for (i = 0; i < 31; i++)
mustersettings.ARSettings.Days[i] = 1;
for (i = 0; i < 24; i++)
{
mustersettings.ARSettings.Time[i].Enable = 0;
mustersettings.ARSettings.Time[i].Hour = (byte)i;
mustersettings.ARSettings.Time[i].Min = 0;
mustersettings.ARSettings.Time[i].Sec = 0;
}
Rec = XXXXComm.comm(CFeCmd.W_MusterAutoRead,(Object)mustersettings);
if (Rec == 0)
{
//成功
}
转发至微博
转发至微博
评论