Page 1 of 1

Managed C#, SIMCONNECT_RECV_CLIENT_DATA data question

Posted: Wed Feb 06, 2019 5:09 am
by ScottB26
I have set up a C# managed program to receive SIMCONNECT_CLIENT_DATA_REQUEST_FLAG.CHANGED data with .RequestClientData. I have a marshaled structure which mirrors the client data structure.

Code: Select all

 [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct PMDG_747QOTSII_Data  { ...};
  
I set up SimConnect with the following:

Code: Select all

simconnect.MapClientDataNameToID(PMDG_747QOTSII_DATA_NAME, PMDG_747QoTSII.PMDG_747QOTSII_DATA_ID);

simconnect.AddToClientDataDefinition(PMDG_747QoTSII.PMDG_747QOTSII_DATA_DEFINITION, 0, (uint) Marshal.SizeOf(typeof(PMDG_747QOTSII_Data)), 0, 0);

simconnect.RequestClientData(   PMDG_747QoTSII.PMDG_747QOTSII_DATA_ID, 
                                                DATAREQUEST_ID.DATA_REQUEST, 
                                                PMDG_747QoTSII.PMDG_747QOTSII_DATA_DEFINITION, 
                                                SIMCONNECT_CLIENT_DATA_PERIOD.ON_SET, 
                                                SIMCONNECT_CLIENT_DATA_REQUEST_FLAG.CHANGED, 
                                                0, 0, 0);
                                                
simconnect.OnRecvClientData += new SimConnect.RecvClientDataEventHandler(simconnect_OnRecvClientData);                                                
  
I can successfully trigger the data event by toggle the aircraft switches thereby invoking the following:

Code: Select all

        
        void simconnect_OnRecvClientData(SimConnect sender, SIMCONNECT_RECV_CLIENT_DATA data)
        {
            switch ((DATAREQUEST_ID)data.dwRequestID)
            {
                case DATAREQUEST_ID.DATA_REQUEST:

                    // I reach this point ok.
                    
                    // How do I read the data?
                    
                    // I have tried the following but things do not work.
                    
                    PMDG_747QOTSII_Data s1 = (PMDG_747QOTSII_Data)data.dwData[0]; //this does not work!!

		    displayText("LTS_Taxi_Sw_ON: " + s1.LTS_Taxi_Sw_ON);
                    
                    break;

                default:
                    displayText("Unknown request ID: " + data.dwRequestID);
                    break;
            }
        }
        
Essentially, the basic plumbing works except I cannot cast the 'data' object to my 'PMDG_747QOTSII_Data ' structure type and access the data.

Would some kind soul set me straight?

Cheers,
Scott434/ScottB26

Re: Managed C#, SIMCONNECT_RECV_CLIENT_DATA data question

Posted: Mon Mar 11, 2024 12:41 pm
by phlerp
Sorry for bringing up an old thread that nobody has answered on, but I have the exact same problem.
I am trying to send client data between a number of Simconnect clients by using ClientData. Currently the sending client is a managed C# application, and the two receiving applications are one native C++ and one managed C#. The native C++ application is written a long time ago and is actually implementing simconnect for FSX, but it works just fine and receives all data it should. So it apparently works fine sending client data from a managed application and receive in a native C++ application.

However my receiving managed C# application does not receive the right data. When looking in the debugger into the dwData array in SIMCONNECT_RECV_CLIENT_DATA, it only has the size of 4 byte though it should be 8 bytes. The result is the same no matter what data structures I define and send.

I vaguely remember people saying that managed client data handling was broken back in the FSX days, but I would have expected that to be fixed by now. Is this a known problem or am I doing something wrong?

Re: Managed C#, SIMCONNECT_RECV_CLIENT_DATA data question

Posted: Mon Mar 11, 2024 3:09 pm
by phlerp
I found this way to go around the problem.

https://www.fsdeveloper.com/forum/threa ... ost-154889
While updating SDK of my FSX add-on (thanks Simon, thanks Geoff) I encountered RegisterDataDefineStruct SimConnect managed wrapper
marshaller issue: the marshaller does not make it possible to receive Client Data. Later I found that this problem is already known.
To fix this issue I have written a small piece of C# code (see below). It works fine in my case and I hope will help other developers too.

To enable Client Data receiving the following method is used:

Code:

Code: Select all

public void RegisterClientDataDefineStruct<T>(Enum dwID)
{
    simconnect.RegisterStruct<SIMCONNECT_RECV_CLIENT_DATA, T>(dwID);
}

simconnect is a SimConnect object.

This method must be called after the last AddToClientDataDefinition managed wrapper API function call:

Code:

Code: Select all

simconnect.MapClientDataNameToID(...);
...
simconnect.AddToClientDataDefinition(DEFINITIONS.Struct1, ...);
this.RegisterClientDataDefineStruct<Struct1>(DEFINITIONS.Struct1);
Struct1 and DEFINITIONS.Struct1 are Client Data structure and its definition ID respectively, also in this example it's assumed that
RegisterClientDataDefineStruct method defined in the same class.

All this is needed for Client Data receiving only as for FSX Data receiving the native RegisterDataDefineStruct marshaller can be used
successfully. Also it should be remembered that in some cases specific information (attributes) must be provided with Client Data structure(s)
as described in SimConnect SDK.
It is originally for FSX but it seems to work for Prepar3D too. However I still consider this as a bug that needs to be fixed. I have many Simconnect clients relying on ClientData and I need to port them to C#.