CLIENT RTD (COM)

JULIANO ZUCATTI 1 Reputation point
2021-08-09T23:16:08.267+00:00

I'm building a client to receive data from the RTD server
I'm using this example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
namespace DotNet2
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            chamaMetodo("RTDTrading.RTDServer");
        }

        private static void chamaMetodo(string v)
        {

            RtdClient rtd = new RtdClient(v);
            Console.WriteLine("rtd:"+rtd);

            object[] param = new Object[2];
            param[0] = "DOLFUT_F_0";
            param[1] = "HOR";
            Object ret = rtd.GetValue(param);
            Console.WriteLine("ret:"+ret);
        }
    }

}

Class Interface:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

namespace DotNet2
{
    public interface IRtdClient
    {
        object GetValue(params object[] args);
    }

    public class RtdClient : IRtdClient
    {
        readonly string _rtdProgId;
        static IRtdServer _rtdServer;


        public RtdClient(string rtdProgId)
        {
            _rtdProgId = rtdProgId;
        }

        public object GetValue(params object[] args)
        {

            const int topicCount = 1;
            var rnd = new Random();
            var topicId = rnd.Next(int.MaxValue);
            var rtdServer = GetRtdServer();
            Console.WriteLine("TopicID "+topicId+" args:"+args[0]+" args2:"+args[1]);

            rtdServer.ConnectData(topicId, args, true);

            object val = null;
            while (val == null)
            {
                var alive = rtdServer.Heartbeat();

                if (alive != 1)
                    GetRtdServer();
                else
                {
                    //var refresh = new object[0,0];
                    var refresh = rtdServer.RefreshData(topicCount);
                    if (refresh.Length <= 0) continue;

                    if (refresh[0, 0].ToString() == topicId.ToString())
                    {
                        val = refresh[1, 0];
                    }
                }
            }

            rtdServer.DisconnectData(topicId);

            return val;
        }

        IRtdServer GetRtdServer()
        {
            if (_rtdServer == null)
            {
                Type rtd = Type.GetTypeFromProgID(_rtdProgId);
                _rtdServer = (IRtdServer)Activator.CreateInstance(rtd);
            }
            return _rtdServer;
        }
    }

    [ComImport,
        TypeLibType((short)0x1040),
        Guid("EC0E6191-DB51-11D3-8F3E-00C04F3651B8")]
    public interface IRtdServer
    {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(10)]
        int ServerStart([In, MarshalAs(UnmanagedType.Interface)] IRTDUpdateEvent callback);

        [return: MarshalAs(UnmanagedType.Struct)]
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(11)]
        object ConnectData([In] int topicId, [In, MarshalAs(UnmanagedType.SafeArray,
                                                SafeArraySubType = VarEnum.VT_VARIANT)] ref object[] parameters, [In, Out] ref bool newValue);

        [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)]
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(12)]
        object[,] RefreshData([In, Out] ref int topicCount);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(13)]
        void DisconnectData([In] int topicId);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(14)]
        int Heartbeat();

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(15)]
        void ServerTerminate();
    }

    [ComImport,
        TypeLibType((short)0x1040),
        Guid("A43788C1-D91B-11D3-8F39-00C04F3651B8")]
    public interface IRTDUpdateEvent
    {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(10),
            PreserveSig]
        void UpdateNotify();

        [DispId(11)]
        int HeartbeatInterval
        {
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(11)]
            get; [param: In]
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(11)]
            set;
        }

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(12)]
        void Disconnect();
    }

}

In method call:

rtdServer.ConnectData(topicId, args, true);

I get exception:

Unhandled exception. System.Runtime.InteropServices.COMException (0x8000FFFF): Falha catastrófica (0x8000FFFF (E_UNEXPECTED))
   at DotNet2.IRtdServer.ConnectData(Int32 topicId, Object[]& parameters, Boolean& newValue)

Can someone help me ?
I didn't find other examples of client consuming RTD(COM)

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,426 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,279 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,538 questions
{count} votes

1 answer

Sort by: Most helpful
  1. TATI NOVAIS 1 Reputation point
    2022-09-21T18:14:27.913+00:00

    Please, in my tests I came across the following Exception:
    System.Runtime.InteropServices.COMException: 'Access violation at address 00000000004771ED in module 'profitchart.exe'. Read of address 0000000000000010'.

    But I see that he managed to correctly identify which program is the RDT server.
    Any idea what it could be?

    See the syntax in Excel is like this:
    =RTD("rtdtrading.rtdserver";; "WDOFUT_F_0"; "ULT")

    Something to change in the structure?
    Thanks in advance for the code.

    0 comments No comments