C# 中的 RTD 客户端

RTD Client in C#

我正在尝试编写一个简单的 RTD 客户端作为开始,但我似乎无法建立初始连接。我在网上找到了一些例子,最好的似乎是 this RTD client in C# gist.

在 MS-Excel 上有这个:=RTD("rtdtrading.rtdserver",, "WINZ20_F_0", "HOR") - 公式适用于 Excel 并提取新数据。

在上面要点的代码中,我尝试用以下方法实例化对象:

var handler = new RtdClient("rtdtrading.rtdserver");

到目前为止,还不错。但是,当我尝试

var valList = handler.GetValue(new object[] { "WINZ20_G_0", "HOR" });

我遇到了一个很大的灾难性故障(0x8000FFFF(E_UNEXPECTED)) 来自IRtdServer.ConnectData(Int32 topicId, Object[]& parameters, Boolean& newValue)line 24 in the code above

如果我尝试使用 new string[] { "WINZ20_G_0", "HOR" });,则错误会变为 Specified array was not of the expected type,发生得更深一些,但我相信还是在之前ConnectData() 实际上是 运行,如调用堆栈所示:

at System.StubHelpers.MngdSafeArrayMarshaler.ConvertSpaceToNative(IntPtr pMarshalState, Object& pManagedHome, IntPtr pNativeHome)
at ProfitRTDAnalyzer.Program.IRtdServer.ConnectData(Int32 topicId, Object[]& parameters, Boolean& newValue)

我似乎无法正确确定如何处理这个问题。将 object[] refs 更改为 string[] 它们与这些参数(主题列表)相关的地方,也没有帮助(仍然 _array 不是预期的类型)。

根据MS documentation, ConnectData() receives as second parameter a single-dimensional array of strings,所以我不知道这里有什么问题。

为了解决这个问题,我是这样做的:

  1. 创建一个新的 class 来实现 UpdateEvent:
    public class UpdateEvent : IRTDUpdateEvent
    {
        public long Count { get; set; }
        public int HeartbeatInterval { get; set; }

        public UpdateEvent()
        {
            // Do not call the RTD Heartbeat()
            // method.
            HeartbeatInterval = -1;
        }

        public void Disconnect()
        {
            // Do nothing.
        }

        public void UpdateNotify()
        {
            Count++;
        }
    }
  1. 然后,替换成GetRtdServer函数
        IRtdServer GetRtdServer() {
            if (_rtdServer == null) {
                Type rtd = Type.GetTypeFromProgID(_rtdProgId);
                _rtdServer = (IRtdServer) Activator.CreateInstance(rtd);

                // Create the updateEvent.
                UpdateEvent updateEvent = new UpdateEvent();
                _rtdServer.ServerStart(updateEvent);

            }
            return _rtdServer;
        }