基于C# 实现 OPC DA Server
最近研究OPC Server,本着有点啥都可以上网找找源代码会很快搞定。
找了很久基本上都是C++的而且源代码大多是编译不成功的,要么又是部分DLL不提供源码的。
C#的只有客户端源码,且好像也没有能完全运行的。
本人对C++的基础功力实在不是太好,C++代码基本处理能能看得懂但是不能写。
在研究OPC Server前且对COM,DCOM,COM+的理解力为零。OPC 是啥东西都没有听说过,这回是第一次接触工控行业。
最后实在没有办法了。只能靠自己了,于是上网找资料还得是中文资料,英语不好。
最后找到了OPC基金组织提供的C#版接口,该接口主要是作为C#编写客户使用的。本着客户端能用服务端也能的思想,前提是C#也是支持COM,DCOM,COM+的不然直接交枪了。
关于C#怎么编写一个进程外的DCOM组件,这里先不做介绍了。
这里主要先介绍下OPC DA Server 的第一个接口
1 public enum OpcServerState
2 {
3 Failed = 2,
4 NoConfig = 3,
5 Running = 1,
6 Suspended = 4,
7 Test = 5
8 }
9
10 [ComVisible(true), Serializable, StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=2)]
11 public class ServerStatus
12 {
13 ///服务器启动时间
14 public long ftStartTime;
15
16 /// <summary>
17 /// 当前时间
18 /// </summary>
19 public long ftCurrentTime;
20
21 /// <summary>
22 /// 最后一次更新客户的时间
23 /// </summary>
24 public long ftLastUpdateTime;
25
26 /// <summary>
27 /// 当前服务器状态
28 /// </summary>
29 [MarshalAs(UnmanagedType.U4)]
30 public OpcServerState eServerState;
31
32 /// <summary>
33 /// 本服务器实例所管理的组对象数
34 /// </summary>
35 public int dwGroupCount;
36
37 /// <summary>
38 /// 当前使用带宽的百分比,现在返回未知 0xFFFFFFFF
39 /// </summary>
40 public int dwBandWidth;
41
42 /// <summary>
43 /// 主版本号
44 /// </summary>
45 public short wMajorVersion;
46
47 /// <summary>
48 /// 副版本号
49 /// </summary>
50 public short wMinorVersion;
51
52 /// <summary>
53 /// 编译号
54 /// </summary>
55 public short wBuildNumber;
56
57 /// <summary>
58 /// 保留
59 /// </summary>
60 public short wReserved;
61
62 /// <summary>
63 /// 厂商信息
64 /// </summary>
65 [MarshalAs(UnmanagedType.LPWStr)]
66 public string szVendorInfo;
67 }
68
69 public class OPCDAServer : IOPCServer, IOPCCommon,
70 IOPCBrowseServerAddressSpace, IOPCItemProperties
71 , IOPCBrowse, IOPCItemIO, IOPCServerPublicGroups,IDisposable
72 {
73 /// <summary>
74 /// 获取服务器基本信息
75 /// </summary>
76 /// <param name="ppServerStatus">输出参数 服务器信息结构</param>
77 /// <returns></returns>
78 [PreserveSig]
79 public int GetStatus(out ServerStatus ppServerStatus)
80 {
81 ppServerStatus = new ServerStatus();
82 ppServerStatus.eServerState = OpcServerState.Running;
83 ppServerStatus.szVendorInfo = "公司-个人组织";
84 ppServerStatus.dwGroupCount = 10;
85 ppServerStatus.ftCurrentTime = DateTime.Now.ToFileTime();
86 ppServerStatus.ftLastUpdateTime = DateTime.Now.ToFileTime();
87 ppServerStatus.ftStartTime = DateTime.Now.ToFileTime.ToFileTime();
88 ppServerStatus.wMajorVersion = 1;
89 ppServerStatus.wMinorVersion = 1;
90 ppServerStatus.wBuildNumber = 0;
91 return HRESULTS.S_OK;
92 }
93 }
2 {
3 Failed = 2,
4 NoConfig = 3,
5 Running = 1,
6 Suspended = 4,
7 Test = 5
8 }
9
10 [ComVisible(true), Serializable, StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=2)]
11 public class ServerStatus
12 {
13 ///服务器启动时间
14 public long ftStartTime;
15
16 /// <summary>
17 /// 当前时间
18 /// </summary>
19 public long ftCurrentTime;
20
21 /// <summary>
22 /// 最后一次更新客户的时间
23 /// </summary>
24 public long ftLastUpdateTime;
25
26 /// <summary>
27 /// 当前服务器状态
28 /// </summary>
29 [MarshalAs(UnmanagedType.U4)]
30 public OpcServerState eServerState;
31
32 /// <summary>
33 /// 本服务器实例所管理的组对象数
34 /// </summary>
35 public int dwGroupCount;
36
37 /// <summary>
38 /// 当前使用带宽的百分比,现在返回未知 0xFFFFFFFF
39 /// </summary>
40 public int dwBandWidth;
41
42 /// <summary>
43 /// 主版本号
44 /// </summary>
45 public short wMajorVersion;
46
47 /// <summary>
48 /// 副版本号
49 /// </summary>
50 public short wMinorVersion;
51
52 /// <summary>
53 /// 编译号
54 /// </summary>
55 public short wBuildNumber;
56
57 /// <summary>
58 /// 保留
59 /// </summary>
60 public short wReserved;
61
62 /// <summary>
63 /// 厂商信息
64 /// </summary>
65 [MarshalAs(UnmanagedType.LPWStr)]
66 public string szVendorInfo;
67 }
68
69 public class OPCDAServer : IOPCServer, IOPCCommon,
70 IOPCBrowseServerAddressSpace, IOPCItemProperties
71 , IOPCBrowse, IOPCItemIO, IOPCServerPublicGroups,IDisposable
72 {
73 /// <summary>
74 /// 获取服务器基本信息
75 /// </summary>
76 /// <param name="ppServerStatus">输出参数 服务器信息结构</param>
77 /// <returns></returns>
78 [PreserveSig]
79 public int GetStatus(out ServerStatus ppServerStatus)
80 {
81 ppServerStatus = new ServerStatus();
82 ppServerStatus.eServerState = OpcServerState.Running;
83 ppServerStatus.szVendorInfo = "公司-个人组织";
84 ppServerStatus.dwGroupCount = 10;
85 ppServerStatus.ftCurrentTime = DateTime.Now.ToFileTime();
86 ppServerStatus.ftLastUpdateTime = DateTime.Now.ToFileTime();
87 ppServerStatus.ftStartTime = DateTime.Now.ToFileTime.ToFileTime();
88 ppServerStatus.wMajorVersion = 1;
89 ppServerStatus.wMinorVersion = 1;
90 ppServerStatus.wBuildNumber = 0;
91 return HRESULTS.S_OK;
92 }
93 }
上段代码就是IOPCServer接口中GetStatus方法的实现,其它方法实现后面有时间继续。
付上测试图
这本人第一次写博客,有不清楚的请亮解。有错字纯属正常。