simconnect-rust
simconnect-rust copied to clipboard
32-Bit SimConnect Support (32-bit Prepar3D)
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
andshell32.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 arustup
target using:-
rustup install stable-i686-pc-windows-msvc
andrustup 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 resultingltod.lib
into thelibsrc/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:
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.
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
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.
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
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.
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
Alright looks like the MSFS SimConnect headers work anyway. I've updated the branch, so let me know if it works now.
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
~~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
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
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.
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