Simconnect client to be used with both MSFS and P3D

I have a simconnect client app in c# that I want to be able to connect to both MSFS and P3D.
If a user is running MSFS, the client should be able to connect to MSFS and if the user is running P3D it should connect to P3D.

Which version of Microsoft.Flightsimulator.Simconnect.dll should the app be built with and which SimConnect.dll version must be in the app folder?

I would suggest using a custom interface that is using both DLLs (P3D and MSFS), then the App can decide on runtime which to use.

1 Like

Thanks for your suggestion, but it is not clear to me what you actually mean.

basically you have an abstract class, and classes (one for P3D and one for MSFS). Both implement the abstract class.
From your C# App select based on the Current Running Sim, which class you need to intialize on startup.

He means a plugin architecture - think dynamic linking, think plugins, think Photoshop, think the nineties (when plugins were all the rage ;))

So yes, a common interface, two or more distinct implementations. Both DLLs then reside in a well-known application „plugins“ directory and your app loads and links with them at runtime, on demand (see system call dlopen() and friends).

In fact, you basically already have a common interface: it‘s called „SimConnect“ :wink: So I‘d expect the implementations to be nearly identical (and they could hence be provided in a common, abstract base class which implements your plugin interface), give or take some flight simulator specific „boilerplate code“.

Essentially the two plugins would only be different in the SimConnect.dll they link with: for FS2020 you‘d link your plugin with the instance provided in the MSFS SDK, for Prepar3D you‘d link with the SimConnect.dll instance coming from the „Prepar SDK“ (or whatever simulator you want to support).

Because it is essentially the flight simulator specific SimConnect.dll that deals with the specifics (communication protocol, sim specific data structures etc.). Again, when developing against the SimConnect API you already have paid 90% of the entrance fee, so to speak :wink:

P.S. When I said „dlopen()“, don‘t worry: in C# I‘m sure you have a „higher level API“ to „dynamically load/instantiate/link with“ a class „on the class path“ (like in Java with the ClassLoader). And even when in the C/C++ world dthere is usually a framework (Qt in my case) involved which provides more convenient APIs, too (e.g. QPluginLoadern)

You can include both DLLs - they have different names, so your users can easily choose between which sim to connect to. Most of the code to talk to the two dlls will be pretty similar, if not identical, so implementing that as an abstract base class makes a lot of sense. That’s essentially what I do in Plan-G.

That‘s even simpler than my previously suggested plugin architecture, but a bit more cumbersome for the end user (but an installer could simplify the process of copying the desired SimConnect.dll into the app directory).

Of course that solution would also be less flexible for the end user - unless the user exchanges the DLLs before (re-)starting the app.

Then again: how many users really use two sims „in parallel“, so this might more be an academic problem.

Of course that requires that the SimConnect.dll libraries are binary compatible. As the SimConnect is a simple C library (API) they should be - are they?

Oh, hold on, do you mean to link your application against both libraries at the same time when you say that „they have different names“? Wouldn‘t that duplicate symbols?

Or what exactly did you mean by „ship both libraries to the end user“?

No, because the library name is part of the symbol name. So in one class file you’d have (very simplified):

using Microsoft.FlightSimulator.Simconnect;
...
class MSFSConnection
{
    private SimConnect _sc;
    public bool Connect(System.IntPtr myWindow)
    {
        bool retVal = false;
        try{
             _sc = new SimConnect("My App Connection", myWindow, WM_USER_SIMCONNECT, null, 0);
            retVal = true;
        }catch(ComException) {}
        return retVal;
    }
}

And in another:

   using LockheedMartin.Prepar3D.Simconnect;
    ...
    class P3DConnection
    {
        private SimConnect _sc;
        public bool Connect(System.IntPtr myWindow)
        {
            bool retVal = false;
            try{
                 _sc = new SimConnect("My App Connection", myWindow, WM_USER_SIMCONNECT, null, 0);
                retVal = true;
            }catch(ComException) {}
            return retVal;
        }
    }

Obviously you need to add both DLLs as dependencies in the project, which means they’ll both be included in the compiled output. You don’t need to worry about which one to copy.
For the user it’s just a matter of clicking “Connect to MSFS” or “Connect to P3D” (or however you want to make your UI). When you know which sim, you can call the appropriate routines (or you can call them through an abstract base class, which is more elegant, but a bit more work. )

The DLLs are very much not binary compatible. They implement the same interface is all, otherwise they should be regarded as totally different animals, at least internally.

By using two sims “in parallel”, if you mean running both at the same time, I don’t imagine that happens very often, not on the same computer anyway. Although across multiple PCs it could happen, especially in test or QA environments. This would only allow one connection at a time, but personally, I’ve never been asked to support simultaneous connections to multiple sims, so I don’t think it’s an issue. If you mean having both sims installed and switching between them at different times, then yes I think that’s likely. If you pay heed to the tantrum threads in this forum, then it may even be quite common (“waaah MSFS is rubbish, I’m going back to P3D/X-Plane/FSX/Legos…”)

1 Like

Oh one other thought: you need to put some thought into what sim versions you want your app to support, because simconnect versions are not backwards compatible. By which I mean you can’t use MSFS SimConnect to connect to FSX. And you can’t use P3dV5 SimConnect to connect to P3Dv4.

But they are FORWARDS compatible. So FSX simconnect will connect to both FSX and MSFS, and P3Dv4 SimConnect will connect to both v4 and v5.

Now, what you want to support is entirely up to you, but it can certainly be argued that more compatibility = more users. So you might think, link to the older versions of SimConnect and job done. But there is a gotcha: all versions of SimConnect before MSFS and P3Dv5 are 32-bit. MSFS and P3Dv5 Simconnects are 64-bit. Architecturally you can’t mix and match them: it’s either all 32-bit or all 64-bit. That might be important to your app, or it might not. But it’s something you should be aware of.

1 Like

Ah, I forgot: the magic voodoo wizardry of „higher level languages“ like C# which „manage“ the underlying gory parts, namely having to mess around with the „raw C API“ :wink:

Now I fully understand, yes, that makes sense now!

In the C/C++ world where I „live“ the symbols (= function names, global variables) are simply named e.g.

SimConnect_Open()

etc. (respectively the „symbol name“ that the C/C++ compiler generates out of it), so no namespace whatsoever to distinguish between the FS2020 and P3D implementation.

So one needs to take care of this „programatically“ in the C/C++ world and carefully link the corresponding SimConnect.dll to the respective plugin code (library).

Oh and what I meant with „in parallel“ was „one day you play A, and the next day you play B“ - if the user had to „manually“ exchange the SimConnect.dll of the desired „flight simulator of the day“ then this would be annoying.

But again, this is not a problem in the „managed world“ of C# and friends :wink:

1 Like

Yes, the OP did specifically mention c#, so we’re in the rarefied heights of managed code, rather than the nuts & bolts underbelly of C/C++ :wink:

But I do take your point that with C/C++ we’d need to worry much more about the library that we’re talking to (I’ve spent a lot of time dealing with “DLL Hell”, its not a fun place to be. Even worse of you have to switch libraries for the “sim of the day”).

1 Like

Yes indeed: for a moment I forgot that others have a better life than I do :wink:

But seriously: C++ is still my language of choice when it comes to hobby desktop applications such as my current pet project.

Together with a decent framework like Qt you can pretend to be in the „high level language league“ :wink:

And interestingly C++ has still gained (or rather: „caught up with other languages“) some interesting new features in the last couple of years.

Well, to be clear: with a plugin architecture you would avoid that the user had to worry about „which DLL to use“ as well: essentially exactly what you do in your C# application: the user would simply choose - in the GUI - with which simulator to connect with and the proper plugin (linking with the vendor-specific SimConnect.dll) would be instantiated (or ideally the app would automatically detect which simulator is currently running).

My point is: that‘s exactly what the „managed“ (?) part is doing for you in C#: from an API point of view you have a clear distinction between the FS2020 and P3D API implementation (-> namespaces), and I assume the underlying implementation (the „managed“ part of it) is dynamically linking - at runtime - with the respective SimConnect.dll, making sure that their (identical) symbols such as the mentioned „SimConnect_open“ do not collide.

And the same is of course also possible in C++ - except in a „do it yourself“ manner and that you are given a gazillion more options to shoot yourself into your foot :wink:

1 Like

Interesting subject. Having started looking at MSFS and Prepar3D, I already noticed more differences. Naturally the Prepar3D SimConnect API has a lot of stuff concerning military matters, missions, weapons systems, countermeasures, and such, but also more generic differences like wide character strings and 64bit values on events. I don’t know why yet, but the PrepaR3d static library will fail to connect to MSFS, but the MSFS one will connect to Prepar3D, even though it lacks the additional functionality.

I think I’ll add two InterOp DLLs to CsSimConnect, one for each, but need to do some “UnsupportedException” checking.

Has anyone gotten the P3D simconnect.dll (ver 3 or 4 or 5) to work with MSFS? I could only get P3D ver 1.4) to work - which is very close to the FSX one. (but I did try a long time ago)

To be honest I’d be surprised if that would work at all. Unless the actual protocol between client (“your app”) and server (“the flight simulator”) was also standardised - is it? - compatibility is usually only given (at the mercy of the vendor) between a given “product line”. So e.g. the “SimConnect.dll” (for simplicity’s sake I call them all “SimConnect.dll”, even though I noticed a couple of days ago that the one from Prepar3D v5 is apparently called “LockheedMartin.Prepar3D.SimConnect.dll”) from FSX might be binary compatible with later incarnations of “Flight Simulator” (including FS2020 perhaps?), and perhaps also with Prepar3D.

The “opposite” however might not necessarily true, so taking a “Prepar3D SimConnect.dll” and try to connect with FS 2020 might or might not work.

So when in doubt always take the DLL that ships with the actual flight simulator.

In my experience it does not work. What I tested and got to work BTW is to have the code choose between two unmanaged DLLs. If they have the same name, you can link the external code with “DllImport”, after using a “LoadLibrary” call to get one of the two from a subdirectory. I am unsure if you can do something like that with Managed DLLs though.