Reading everything except strings in c#, How to retrieve a string from SimConnect in C#?
I’m on my phone so a bit hard to explain. Look at my github project. I have string retrievals in there. GitHub - SAHorowitz/MSFS2020-PilotPathRecorder: Record your flight path with key flight information archived during the Microsoft Flight Simulator 2020 flights. Then export that data to a KML file to use with Google Earth for 3 dimensional flight analysis
Here’s a more direct snippet:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct GENERIC_DATA
{
// ...
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string title;
// ...
}
And when you register it use the string type instead of SIMCONNECT_DATATYPE.FLOAT64
:
m_simConnect.AddToDataDefinition(definition, "Title", null,
SIMCONNECT_DATATYPE.STRING256, 0.0f, SimConnect.SIMCONNECT_UNUSED);
Also, you may edit your post and change the category to just “SDK Discussion” - this isn’t a tutorial.
Thanks, useful , but I’m missing something …
I create simconnect and assign
simconnect.OnRecvSimobjectData += new SimConnect.RecvSimobjectDataEventHandler(SimConnect_OnRecvSimobjectData);
set structure for the Aircraft title (like in the previous post “title”
simconnect.RegisterDataDefineStruct<SimEnvironmentDataStructure> (DEFINITIONS.SimEnvironmentDataStructure);
then request data (the OBJ_ID_USER == 0)
simconnect.RequestDataOnSimObject(DATA_REQUESTS.SimEnvironmentReq, DEFINITIONS.SimEnvironmentDataStructure, SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD.ONCE, SIMCONNECT_DATA_REQUEST_FLAG.DEFAULT, 0, 0, 0);
then the handler does not fire but I get an exception #3 << ERROR
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct SimEnvironmentDataStructure
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string title;
}
everything is working in this app (connection, getting data, sending values)
but I can’t get this string data to work
please help
I think that exception (unknown ID) is referring to something else, the above minimal code doesn’t look like it’d produce that error. You can share more code maybe.
thanks, I’ll paste in more cdde, but if I comment out the RequestDataOnSimObject I don’t get an exception (and the other data arrives on (all numeric))
Do you have the problem if you remove CharSet = CharSet.Ansi
?
When I removed the Ansi reference , the Exception didn’t occur but I had a cast error getting the string
in
SimConnect_OnRecvSimobjectData(,
SimEnvironmentDataStructure s1 = (SimEnvironmentDataStructure) data.dwData[0];
You’re missing: m_simConnect.RegisterDataDefineStruct<TData>(definition);
Don’t remove the <TData>
part. TData is what you want to cast to.
I have
simconnect.RegisterDataDefineStruct
<SimEnvironmentDataStructure>
(DEFINITIONS.SimEnvironmentDataStructure);
((The TData part was not showing in these posts because I needed to add a backshash before the “<”))
My SimConnect application is working … sending and receiving data … except for receiving strings.
Here’s my code C# for the attempt to get TITLE
- DEFINE STRUCTURE
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AircraftTitleDataStructure
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string title;
}
- AFTER CONNECTED setup the HANDLER
simconnect.OnRecvSimobjectData += new SimConnect.RecvSimobjectDataEventHandler(SimConnect_OnRecvSimobjectData);
3a. THEN Add the column to the DataDefinition
simconnect.AddToDataDefinition(DEFINITIONS.AircraftTitleDataStructure, “TITLE”, null, SIMCONNECT_DATATYPE.STRING256, 0.0f, SimConnect.SIMCONNECT_UNUSED);
3b. next REGISTERED the DataStructure
simconnect.RegisterDataDefineStruct(DEFINITIONS.AircraftTitleDataStructure);
- THEN REQUESTED TITLE
simconnect.RequestDataOnSimObject(DATA_REQUESTS.AircraftTitleRequest, DEFINITIONS.AircraftTitleDataStructure,
SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD.ONCE, SIMCONNECT_DATA_REQUEST_FLAG.DEFAULT, 0, 0, 0);
- THIS correctly GENERATES A CALL Back TO THE RECEIVE FUNCTION THAT ALMOST WORKS
void SimConnect_OnRecvSimobjectData(SimConnect sender, SIMCONNECT_RECV_SIMOBJECT_DATA data)
{
switch ((DATA_REQUESTS)data.dwRequestID)
{
case DATA_REQUESTS.DataRequest:
SimPlaneDataStructure s1 = (SimPlaneDataStructure) data.dwData[0];
UseData(s1);
break;
case DATA_REQUESTS.AircraftTitleRequest: // this is the case entered
uint a = data.dwRequestID; //ok
uint b = data.dwID; //ok
var t1 = data.GetType(); //ok
var x = data.dwData[0]; //
string test = x.ToString();
try
{
AircraftTitleDataStructure s2 = (AircraftTitleDataStructure) data.dwData[0]; //note this GENERATES CAST EXCEPTION
DisplayAircraftTitle(s2.title);
}
catch (Exception ex)
{
this.Title = ex.Message;
}
break;
///
///
///
also tried (in the data structure)
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
the error is
ex.Message = “Specified cast is not valid.”
_data = {System.Collections.ListDictionaryInternal}
So I assume the structure and request are ok since it generates the callback … All the data in the callback looks ok except the cast
thanks to GeekyGameDad
I just verified all this works. You are changing lots of things and not understanding how you are breaking the interop, and that is making this more confusing.
The thing that is wrong is your struct:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
You need Pack=1. You must not have CharSet=Ansi.
I think that’s your only problem.
The solution I posted here works with strings, it may provide some assistance.
Below are snippets from that code, relevant to your problem.
I submit the initial request using:
var unit = request.Unit;
if (unit?.IndexOf("string") > -1)
{
unit = null;
}
// Fetch the values suitable for transmission to SimConnect
var simReq = new SimVarRequest
{
ID = RequestID++,
Request = request
};
// Submit the SimVar request to SimConnect
simConnect.AddToDataDefinition(simReq.DefID, request.Name, unit, simReq.SimType, 0.0f, SimConnect.SIMCONNECT_UNUSED);
I submit the Data Structure using:
simConnect.RegisterDataDefineStruct<SimVarString>(simReq.DefID);
Finally, below is my model class for SimVarString above:
internal struct SimVarString
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string Value;
}
Note: I have not declared the structure with [StructLayout…], only the [MarshalAs…] is required.
Hope this helps…
thanks. What I’m trying to figure out now is how to get/set Approach Mode on A320 (tried many vars) … and how to get a list of Waypoints. I found the Waypoint rquest and callback function, I created a waypoint struct and make the request but never get a callback.
I’d suggest making another post for that, so it doesn’t get lost in this thread, otherwise others won’t know to answer, as the subject of this thread is unrelated.