Sign in to follow this  
Guest Soccy

Simconnect C# Waypoints

Recommended Posts

Hi,I just can't figure out, why my waypoints not working.I always get this error: System.ArgumentException was unhandledMessage="Type 'Microsoft.FlightSimulator.SimConnect.SIMCONNECT_DATA_WAYPOINT[]' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed." Here is my code:--------------------------... (Here I init a helicopter, what's working fine) ...Now I come to the waypoints thing:SIMCONNECT_DATA_WAYPOINT[] wp = new SIMCONNECT_DATA_WAYPOINT[3];wp[0].Flags = (uint)SIMCONNECT_WAYPOINT_FLAGS.SPEED_REQUESTED; wp[0].Altitude = 380; wp[0].Latitude = 50.03650093660728; // EDDF Frankfurt Main Position wp[0].Longitude = 8.563154252011499; wp[0].ktsSpeed = 10; wp[0].percentThrottle = 0; wp[1].Flags = (uint)SIMCONNECT_WAYPOINT_FLAGS.SPEED_REQUESTED; wp[1].Altitude = 600; wp[1].Latitude = 450.03650093660728; wp[1].Longitude = 8.463154252011499; wp[1].ktsSpeed = 10; wp[1].percentThrottle = 0; wp[2].Flags = (uint)SIMCONNECT_WAYPOINT_FLAGS.WRAP_TO_FIRST | (uint)SIMCONNECT_WAYPOINT_FLAGS.SPEED_REQUESTED; wp[2].Altitude = 800; wp[2].Latitude = 50.03650093660728; wp[2].Longitude = 8.663154252011499; wp[2].ktsSpeed = 10; wp[2].percentThrottle = 0; simconnect.AddToDataDefinition(DEFINITION_ID.DEFINITION_WAYPOINT, "AI Waypoint list", "AI", SIMCONNECT_DATATYPE.WAYPOINT, 0.0f, SimConnect.SIMCONNECT_UNUSED); simconnect.RegisterDataDefineStruct(DEFINITION_ID.DEFINITION_WAYPOINT);simconnect.SetDataOnSimObject(DEFINITION_ID.DEFINITION_WAYPOINT, MooneyID, SIMCONNECT_DATA_SET_FLAG.DEFAULT, wp); //<--- HERE ACTUALLY THE ERROR APPEARS, I suppose about the wp-struct!-------------------------I have no clue what I do wrong, since simconnect should handle all Marshaling issues. The error must deal with the "wp"-Structure, but I dunno what is wrong.Im looking forward any tips/help with this!!Thanx alot,Chris.PS: Somehow this forum showing some code brackets in a wrong way. I.ex. with wp<1> it is normally [ ] .... I do have these correct in my code, just if you think it might be that:) Tx!

Share this post


Link to post
Share on other sites
Help AVSIM continue to serve you!
Please donate today!

I've been working ont he same thing.The problem is with sending an array of a user-defined datatype I think. I haven't heard back in regards to this yet, and set it aside for another project.I can send one waypoint through fine, but not an array of them.It has to translate the array type into an unmanaged code type, a SAFEARRAY, I believe, but I haven't tested it yet.I hope this makes some sense, It's very late and I'm medicated.

Share this post


Link to post
Share on other sites

Hello,this makes sense. Thank you alot for your reply.I also guess it has to deal with the array struct. Hopefully someone can post a working sample here, that would be great. Actually I did my thingy in C++ instead of C# and it's working fine there. But C# is better for some windows stuff in my poor opinion, so I'm really looking forward a solution.Greetings, Chris.

Share this post


Link to post
Share on other sites

There are a number of marshaling issues with the provided managed class, which caused me to say the heck with it and I'm 90% completed writing my own wrapper to the native simconnect library in C#.In all fairness, marshaling the pointers sent back by the C++ API can be a challenge. The code is truly designed for use with pointer arithmetic, and pointer to pointer to pointers, the kind of stuff hardcore C devs love and relish. Marshaling variants and nested arrays is quite the challenge from managed code. The entire design of managed code goes precisely against the pointer to whatever philosophy, and a cultural faux-pas in the CLR world. Thankfully there's the unsafe keyword, so all is not lost!I'm not surprised you're running into these issues. I didn't get to the waypoint stuff yet, but just dealing with tagged and untagged values was a hoot. At least, custom marshaling is available to deal with the worst offending return structures.Clearly, managed code with FSX is an afterthought - and I noted the .NET wrapper provided in the SDK is actually written in C++ Interop, not C#, based on the assembly signature and a quick analysis via reflection.I think though there is hope out there with custom marshaling and a bit of unsavory pointer magic in C#.E.

Share this post


Link to post
Share on other sites

Actually, they brought a guy in for some tool building and he said "You know, I can port that over to C#" and so they did.It absolutely was (at first) not the main focus. But all in all, it's working well enough for me.

Share this post


Link to post
Share on other sites

I read your comments very interested and I'm looking forward that marshalling solution.Meanwhile I made some progress, too, so far not about the waypoints (I coded them with C++ instead by now, until I get to know another way). The most other things so far are working fine with managed code. Just in case you are interested, I uploaded a little tool I made, called "FSX Helper", to http://www.clanchat.de. I don't know so far, if it will run at all on your machine, since deploying is not so easy.I would look forward a feedback:- Does it run at all?- What is good, what is bad?Thanx alot,Sincerely,Chris.

Share this post


Link to post
Share on other sites

Hi again,I'm very curious about your feedback, if you try it.That's because the program does not start for a friend of mine, who has not yet installed FSX. So I wonder, if you need FSX to run it. I started a long discussion about that on a C#-Forum (http://www.mycsharp.de/wbb2/thread.php?postid=158331#post158331)and they suggested me, to let someone test it, who has FSX installed. So I kindly ask you to test the tool and report to me, if it will run on your pc. On mine does for sure, on my friend's it does not (but he has not yet FSX). Does it on yours?Tx for your help!CHris

Share this post


Link to post
Share on other sites

Unfortunately, I can't understand most of that, but I see what is happening from the error message. The programs depend on functions from within the SimConnect library that gets included with the header (or the reference, in C#). Without that library, the program will not be able to start.It ran without a hitch on my system. It took me a minute to figure out exactly what everything did, but reading from the webpage helped that out.The autopilot function worked perfectly, although I didn't see anywhere to set what altitude you wanted to be at, and the landing prep was fine too. It was a nice feature.The most helpful part was the quick airport reference. Clicking on the links on the page that showed nearby airports didn't bring anything up for me, but besides that, it was great. I usually have a lot of trouble digging up that info, because I'll be flying around and randomly just decide I want to land somewhere.The only real problem I had was when I was flying, selected a nearby airport and click the button to move me near it. FSX crashed, or at least had a lot of trouble. I didn't give it very long before I killed the process, so it might have just been trying to load the new scenery, and I haven't tried it again. I'll give it another shot.All in all, a very cool little program, and a lot of help. It's sort of like a kneeboard and a co-pilot in one.:DGood work.

Share this post


Link to post
Share on other sites

Thank you very much for your reply!I'm happy, that you like the tool and I'm blushed by your compliment about it. Very happy also, because it is working for you. Meanwhile I also found out, how to make it run on other PCs, which don't have FSX installed or have it in an beta release or other things. Theres a simconnect.msi installation file from Microsoft, that will help to update all necessary libs in case someone won't have them. I bundled that tool to my package, so it will work for everyone now :)About the "Bring nearby"-option: It should work, but indeed it will reload the scenery and other datas, so it will take a min. It should so far really NOT crash your FSX :) About the "Airports nearby"-option: You are right, it won't find nearby airports for each region. Perhaps I can find some day another web service to implement there, which can. For now, it's just a thing you can try. Also the links in that page won't work yet. I need to recode that.So, thank you very much for your time and your very informative test-description. Thanx!

Share this post


Link to post
Share on other sites

No problem, like I said, it's a really useful tool for me.What installer program did you use for it? Inno?

Share this post


Link to post
Share on other sites

Regarding the sending of an array of waypoints from BV or C#:>I've been working ont he same thing.>>It has to translate the array type into an unmanaged code>type, a SAFEARRAY, I believe, but I haven't tested it yet.The notes from the SDK update state this:" Managed Data Arrays - Marshalling of arrays in the managed interface was not working properly; now they are. "Is there an example in C# available of how to do this? My best attempt so far results in a single DATASIZE exception when trying to send a fixed size array, ideally I would like to send a variable size array and get no exceptions :)Edit:Found it, in the general section about managed code:// Step 4: The managed wrapper marshaling code expects a polymorphic arrayDaniel

Share this post


Link to post
Share on other sites

Hi,I want to preface this that I have not yet tried this with this particular structure, but here's the gist of it.The native simconnect object will expect a pointer to a sequence of bytes. The trick is to get the managed code to copy the managed memory into an unmanaged block in the right sequence, then pass to the native function call a pointer to this block.There are several problems to overcome with converting the C++ code for waypoints (uses arrays as you have above) to C#. The first is that default Marshalling in .NET doesn't handle variable sized arrays. The array size must be known at compile time as it is set through an attribute. The second is that the Marshaller doesn't work well with arrays to start with, so you really want to use structures that tell the marshaller what to do based on data types. Keep in mind it needs to work all the way down using reflection to native types (double, float, int, char, and intptr (a C pointer) from the organized struct. Lastly, the managed interface to SimConnect doesn't let you override the data types it exposes to SimConnect, which effectively prevents you from overriding how marshalling works as implemented by the managed wrapper provided in the SDK. So if I want to change data types to the umanaged side, I really don't have access to that (actually, you should be able to usurp that as well with some astute and nasty reflection and exposing the underlying private variables - the complexity may not be worth it!).What I would do in this case is change the call to pass the array to an IntPtr to a block of bytes I've created. This is essentially what a custom marshaller does. Remember that as long as the bytes contain the right sequence, it's doesn't matter on the native (C++ side).This is why a custom marshaller is ideally needed to handle this shortcoming. However, there are a few things you can do with the default marshaller and the provided API now that you are armed with this information.First, use structures. Marshalling uses reflection to examine the fields in each structure to determine how to write out (or read in) a block of unmanaged memory.Second, nest structures to wrap arrays of items. Here's the two structures I would try to use to setup the data: // fixed array of size 3, set by attribute [structLayout(LayoutKind.Sequential, Pack = 1)] public struct SIMCONNECT_DATA_WAYPOINT_FIXED_ARRAY { [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)] SIMCONNECT_DATA_WAYPOINT[] wp; }The other that would marshal to the same thing: [structLayout(LayoutKind.Sequential, Pack = 1)] public struct SIMCONNECT_DATA_WAYPOINT_FIXED_ARRAY { SIMCONNECT_DATA_WAYPOINT wp1; SIMCONNECT_DATA_WAYPOINT wp2; SIMCONNECT_DATA_WAYPOINT wp3; }The last solution, which from what I read is the most common, is simply to define one array member at a time.Hope this helps,Etienne

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this