Search code examples
excelinteroprtd

RTD Client in C#


I'm trying to write a simple RTD client to start with something, but I seem not able to make the initial connection. I have found some examples on the web, and best seemed to be this RTD client in C# gist.

Having this on MS-Excel: =RTD("rtdtrading.rtdserver",, "WINZ20_F_0", "HOR") - formula works on Excel and pulls fresh data.

In the code from the gist above, I then tried to instantiate the object with:

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

So far, so good. But then, when I try to

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

I get a big Catastrophic failure (0x8000FFFF (E_UNEXPECTED)) from IRtdServer.ConnectData(Int32 topicId, Object[]& parameters, Boolean& newValue), line 24 in the code above.

If I try to use new string[] { "WINZ20_G_0", "HOR" });, then the error changes to Specified array was not of the expected type, happening a bit deeper, but I believe still before ConnectData() is actually run, as the call stack suggestes:

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

I can't seem to properly identify how to handle this. Changing the object[] refs to string[] where they relate to those arguments (the topic list), didn't help either (still _array was not of expected type).

According to MS documentation, ConnectData() receives as second parameter a single-dimensional array of strings, so I don't know what is wrong here.


Solution

  • to solve this problem, I have done that:

    1. Create a new class to implement 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. and then, replace it into GetRtdServer function
            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;
            }