Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

32-Bit SimConnect Support (32-bit Prepar3D) #6

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

JohnnyCurran
Copy link

Resolves #5

note: I wouldn't recommend accepting this PR in its current state. Organization needs to be done to split 64/32-bit builds. I imagine you'll have better ideas on how you want that done than I do

This pull request adds the ability to build SimConnect Rust bindings targeting 32-bit versions of Prepar3D (really any 32-bit app that uses the 32-bit version of SimConnect.dll)

It essentially boiled down to a linker issue. Here's how I did it:

  • Pulled user32.lib, ole32.lib and shell32.lib from the Windows SDK for Windows 7 which I was led to by this stackoverflow answer.
  • Added the 32-bit version of SimConnect.dll to the root folder which I got from the Prepar3D v3 SDK
  • Added stable-i686-pc-windows-msvc as a rustup target using:
    • rustup install stable-i686-pc-windows-msvc and rustup add target stable-i686-pc-windows-msvc
  • Stubbed out the missing symbol __ltod3 by creating my own version which just does a direct cast of long to double. No doubt losing precision in the process but I needed it to "just work". Compiled this project and dropped the resulting ltod.lib into the libsrc/lib directory.
  • Tell cargo to look for all included libs in build.rs
  • Build & run the project using Developer Command Prompt for VS2012:
    • cargo +stable-i686-pc-windows-msvc build
    • cargo +stable-i686-pc-windows-msvc run

I think that's everything. If you can reproduce my results that would be fantastic. Here's my lat/lon/altitude from 32-bit P3Dv3:

image

@Sequal32
Copy link
Owner

This is absolutely amazing work you've done! Appreciate you taking the time to research and lots of trial and error I'd imagine. Unfortunately I'm unable to reproduce, but I'm pretty sure it's something to do with conflicting Visual Studio versions...

I followed all the steps you wrote, and running cargo +stable-i686-pc-windows-msvc build in the VS2012 x86 Native Tools Command Prompt, I get LINK : fatal error LNK1181: cannot open input file 'advapi32.lib' which probably means the environment wasn't set up correctly. I tried reinstalling, repairing, and installing window SDKs but I could never get it to compile. Any ideas?

I'm sure I can get it to compile as soon as this issue is resolved but I cannot for the life of me find a solution.

@JohnnyCurran
Copy link
Author

JohnnyCurran commented Mar 21, 2021

I think I forgot to specify you need 32-bit LLVM/Clang installed. I am assuming you do have this because it'll complain earlier in the process about 64/32-bit combat.

Only thing I can think of off the top of my head right now: Inside the Windows 7 SDKs there is an x64 folder as well as a "regular"(?) folder. If you pulled the .lib files from the Win7 SDK folders, make sure they did not come from the x64 folder.

Do you have the P3Dv3 SDK installed? Maybe that has something to do with it

I'll be back in front of my windows machine tomorrow I will clean my install and run through all my steps one-by-one and make sure I didn't miss anything. Which I almost certainly did

Also: Do you have Visual Studio 2013 installed? You probably do given you have the VS2012 prompt but worth an ask anyway

@Sequal32
Copy link
Owner

Sequal32 commented Mar 21, 2021

Yup I installed and set a new LIBCLANG_PATH variable to the 32bit LLVM and I also checked-out your branch for the new lib files. I doubt it has anything to do with the flightsim SDKs as I believe these linker errors refers to not being able to find the windows SDKs.

Something to note that when I first used the VS2012 prompt after installing VS2013 with Update 5 , I got a Cannot determine the location of the VS Common Tools Folder, which I then modifed the vcvars32.bat as per this stackoverflow post.

@JohnnyCurran
Copy link
Author

You said you were using the VS2012 x86 Native Tools Command Prompt? Do you have the Developer Command Prompt for VS2012 installed? Their names are extremely similar but I was building using the latter. Does Developer Command Prompt build successfully? Although I did just try to build a fresh pull of my branch with both terminals, in Administrator mode and not, and was successful both times. Not entirely sure what the difference between all those terminals is though I think the major difference has to do with whichever vcvars*.bat it executes on startup.

In any case, are you able to pull AdvAPI32.lib into the libsrc/include folder and add a line to build.rs to look for it there, specifically? Does that fix the linker issue? Mine is located at C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib. That's not, obviously, an ideal solution, but at least something to get it at least built for now

@Sequal32
Copy link
Owner

Alright it seemed to have been something with my vcvars32.bat not finding the Windows SDK or something. I added these lines to it to help the linker out and it seems to have compiled successfully!

SET LIB=%LIB%;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\x86
SET INCLUDE=%INCLUDE%;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared
SET LIBCLANG_PATH=C:\Program Files (x86)\LLVM32\bin

Since I don't have P3D, I replaced the SimConnect.lib and SimConnect.dll with the ones from FSX:SE and lo and behold it works! I read somewhere that P3D should be backward compatible with the FSX simconnect, so let me know if the fsx branch on the main repository still works for you.

@JohnnyCurran
Copy link
Author

Awesome! Excited to hear you got it up and running and I'm glad it doesn't only work on my machine.

I checked out the fsx branch but I got a ton of errors which I suspected were due to windows.h not being found:

 --- stdout
  cargo:rustc-link-search=libsrc/lib
  cargo:rustc-link-lib=static=ltod
  cargo:rustc-link-lib=static=SimConnect
  cargo:rustc-link-lib=static=user32
  cargo:rustc-link-lib=static=ole32
  cargo:rustc-link-lib=static=shell32

  --- stderr
  libsrc/include/SimConnect.hpp:30:9: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:36:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:37:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:41:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:45:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:46:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:47:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:48:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:49:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:52:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:59:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:60:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:63:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:64:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:65:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:66:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:67:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:68:14: error: unknown type name 'DWORD'
  libsrc/include/SimConnect.hpp:71:14: error: unknown type name 'DWORD'
  fatal error: too many errors emitted, stopping now [-ferror-limit=]

I re-added #include "Windows.h" to SimConnect.hpp and got past those errors but ran into a bunch of type not found issues:

error[E0412]: cannot find type `SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED` in this scope
  --> src\lib.rs:95:39
   |
95 |     EventMultiplayerServerStarted(&'a SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED),
   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type `SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED` in this scope
  --> src\lib.rs:96:39
   |
96 |     EventMultiplayerClientStarted(&'a SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED),
   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type `SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED` in this scope
  --> src\lib.rs:97:38
   |
97 |     EventMultiplayerSessionEnded(&'a SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED),
   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type `SIMCONNECT_RECV_EVENT_RACE_END` in this scope
   --> src\lib.rs:98:22
    |
98  |     EventRaceEnd(&'a SIMCONNECT_RECV_EVENT_RACE_END),
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a struct with a similar name exists: `SIMCONNECT_RECV_EVENT_FRAME`
    |
   ::: C:\Users\Redbird\dev\simconnect-rust\target\debug\build\simconnect-54c2ee169ab443b7\out/bindings.rs:791:1
    |
791 | pub struct SIMCONNECT_RECV_EVENT_FRAME {
    | -------------------------------------- similarly named struct `SIMCONNECT_RECV_EVENT_FRAME` defined here

error[E0412]: cannot find type `SIMCONNECT_RECV_EVENT_RACE_LAP` in this scope
   --> src\lib.rs:99:22
    |
99  |     EventRaceLap(&'a SIMCONNECT_RECV_EVENT_RACE_LAP),
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a struct with a similar name exists: `SIMCONNECT_RECV_EVENT_FRAME`
    |
   ::: C:\Users\Redbird\dev\simconnect-rust\target\debug\build\simconnect-54c2ee169ab443b7\out/bindings.rs:791:1
    |
791 | pub struct SIMCONNECT_RECV_EVENT_FRAME {
    | -------------------------------------- similarly named struct `SIMCONNECT_RECV_EVENT_FRAME` defined here

error[E0412]: cannot find type `SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED` in this scope
   --> src\lib.rs:467:176
    |
467 | ...mute_copy(&(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED)))),
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type `SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED` in this scope
   --> src\lib.rs:468:176
    |
468 | ...mute_copy(&(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED)))),
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type `SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED` in this scope
   --> src\lib.rs:469:174
    |
469 | ...mute_copy(&(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED)))),
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type `SIMCONNECT_RECV_EVENT_RACE_END` in this scope
   --> src\lib.rs:470:141
    |
470 | ..._buf as *const SIMCONNECT_RECV_EVENT_RACE_END)))),
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a struct with a similar name exists: `SIMCONNECT_RECV_EVENT_FRAME`
    |
   ::: C:\Users\Redbird\dev\simconnect-rust\target\debug\build\simconnect-54c2ee169ab443b7\out/bindings.rs:791:1
    |
791 | pub struct SIMCONNECT_RECV_EVENT_FRAME {
    | -------------------------------------- similarly named struct `SIMCONNECT_RECV_EVENT_FRAME` defined here

error[E0412]: cannot find type `SIMCONNECT_RECV_EVENT_RACE_LAP` in this scope
   --> src\lib.rs:471:141
    |
471 | ..._buf as *const SIMCONNECT_RECV_EVENT_RACE_LAP)))),
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a struct with a similar name exists: `SIMCONNECT_RECV_EVENT_FRAME`
    |
   ::: C:\Users\Redbird\dev\simconnect-rust\target\debug\build\simconnect-54c2ee169ab443b7\out/bindings.rs:791:1
    |
791 | pub struct SIMCONNECT_RECV_EVENT_FRAME {
    | -------------------------------------- similarly named struct `SIMCONNECT_RECV_EVENT_FRAME` defined here

error: aborting due to 10 previous errors

It looks like most of these symbols were removed in the most recent commit of the fsx branch. Some of the missing symbols were removed here

@Sequal32
Copy link
Owner

Alright looks like the MSFS SimConnect headers work anyway. I've updated the branch, so let me know if it works now.

@JohnnyCurran
Copy link
Author

I can build, but I get the following runtime error:

The procedure entry point SimConnect_AddToDataDefinition could not be located in the dynamic link library C:\path\to\repo\target\debug\simconnect.exe

@Sequal32
Copy link
Owner

Sequal32 commented Mar 23, 2021

Is it possible you're using another SimConnect.dll that's not the one in the repo? I know that I have to move the SimConnect.dll from your repo to my CWD since I'm in a cargo workspace.

Scratch that I had the wrong dll in the repo... should be updated now

@JohnnyCurran
Copy link
Author

With the new DLL I can both build & run. Still getting an error from the get_next method but I don't have time yet to dive into why that might be occurring. Just did a quick pull, build, & run and that all was successful

@Sequal32
Copy link
Owner

Hmm alright then it seems like different dlls/lib files are needed to work with P3D and FSX then. This is amazing regardless! if you want you can take a crack at implementing switching between 32bit/64bit, and perhaps feature flags is the way to go with differentiating between P3D/FSX. Otherwise I can merge this and try to implement it when I find the time.

@JohnnyCurran
Copy link
Author

I can try and take a crack at it. I cannot promise any sort of timeline. I would probably branch off of this branch to begin that work anyway

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Is it possible to use this with 32-bit builds of Prepar3D?
2 participants