Jump to content
The simFlight Network Forums

Added Support for LVars/HVars Access in MSFS via John Dowson's WASM Module.


Recommended Posts

Hi Steve,

I found 2 problems, including the delegate potentially being garbage collected (as per the error message).

Can you try 3.2.6-beta please? (You'll need to tick the box 'include prerelease' to see it).

Thanks,

Paul

Link to comment
Share on other sites

  • 1 month later...

Afternoon, Paul

I get a random error trying to access FSUIPC_WAPID.dll; it happens on occasions when I call VS.Start.  Any suggestions?


Faulting module name: FSUIPC_WAPID.dll, version: 0.0.0.0, time stamp: 0x60be530f
Exception code: 0xc0000005

Link to comment
Share on other sites

Hi,

If it's intermittent then it's going to be difficult to track down.

Are you using the latest versions of all the components?

My DLL: 3.2.7

WAPIID.dll: 0.5.0

Latest FSUIPC7 (for the latest wasm module)

Paul

Link to comment
Share on other sites

  • 2 weeks later...
On 7/6/2021 at 2:01 AM, Paul Henty said:

Hi,

If it's intermittent then it's going to be difficult to track down.

Are you using the latest versions of all the components?

My DLL: 3.2.7

WAPIID.dll: 0.5.0

Latest FSUIPC7 (for the latest wasm module)

Paul

Yes sir I am.  It's persistent now; I believe it's an access error but I can't nail it down.  

Link to comment
Share on other sites

The other thing to check is that you're compiling your application as a 64bit application (targeting x64). Or, if your compiling for "Any CPU" make sure you've unchecked "prefer 32-bit".

Since WAPID.DLL is 64 bit your application will also need to be running as a 64bit application.

You'll find these in the project properties under the 'Build' tab.

Paul

Link to comment
Share on other sites

Hi,

I have some problems to use FSUIPC_WAPID (vers 0.5.2) with fsuipcClient (vers 3.2.7.374).

I try to program in c# and i have trhis error message : "An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)".

This error is obtained but making this first line of code:

var VS = new MSFSVariableServices();

My dll run in x64 build.

Link to comment
Share on other sites

Quote

An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)".

That error means there is a mismatch somewhere between 64 and 32 bit. 

Quote

My dll run in x64 build.

Is it compiled to x64 only, or it is "Any CPU"?. If it's "Any" then your DLL will run in 32 bit if the exe or process it's running in is 32 bit.

When the host application is running, check the Windows Task Manager. If it's running as 32 bit it will add this to the end of the name.

Paul

Link to comment
Share on other sites

2 hours ago, Paul Henty said:

That error means there is a mismatch somewhere between 64 and 32 bit. 

Is it compiled to x64 only, or it is "Any CPU"?. If it's "Any" then your DLL will run in 32 bit if the exe or process it's running in is 32 bit.

When the host application is running, check the Windows Task Manager. If it's running as 32 bit it will add this to the end of the name.

Paul

Thanks Paul. I will try to identify in the task Manager.

In my visual studio community i know that my build is configurated to x64.

I will tell you the result.

Link to comment
Share on other sites

23 hours ago, Paul Henty said:

That error means there is a mismatch somewhere between 64 and 32 bit. 

Is it compiled to x64 only, or it is "Any CPU"?. If it's "Any" then your DLL will run in 32 bit if the exe or process it's running in is 32 bit.

When the host application is running, check the Windows Task Manager. If it's running as 32 bit it will add this to the end of the name.

Paul

You were right. The problem was another program who was running under 32Bit thjat as conflict with my dll.

Now everything run fine.

Thanks.

  • Like 1
Link to comment
Share on other sites

On 7/19/2021 at 1:36 PM, kingm56 said:

That was the first thing I checked, my friend 

I don't know what else to suggest, sorry. I've been trying here but I can't reproduce the error and no other users are reporting it. It looks to be something specific to your setup.

Paul

Link to comment
Share on other sites

  • 3 weeks later...

Where can I get "You must use FSUIPC-WASMv0.5.0.zip or a later version."

All the links are dead, need help?

Okay, found a version here:

https://github.com/jldowson/WASMClient/tree/master/WASMClient/FSUIPC_WAPI/lib

But when I put this dll with the fsuipcClient.dll in the same folder, it will not load. I have explicit 64bit build, but unsure what is the build of the FSUIPC_WAPI that I downloaded?

By trying to load this DLL using depends (is a tool to load windows modules) I get an exception:

Error: At least one file was not a 32-bit or 64-bit Windows module.

Looks like this DLL is not a valid windows DLL.

So the question, where can I get a 64 bit version of this DLL?

 

UPDATE:

Do you support Read/Write Lvar in FSUIPCClient v3.2.8 out of the box (with fsuipc version (7.2) having the FSUIPC WASM module installed)???

I noticed that making calls: FSUIPCConnection.WriteLVar/ReadLvar work without explicitly using MSFSVariableServices class. Is this now built-in?

Link to comment
Share on other sites

Quote

Where can I get "You must use FSUIPC-WASMv0.5.0.zip or a later version."

Sorry for the broken links - things are still in development and are getting moved around. I'll amend the post. The latest is 0.5.2. Here is the link:

http://www.fsuipc.com/download/FSUIPC-WASMv0.5.2.zip

If your browser blocks this direct link, goto:

http://www.fsuipc.com/

and search for 'WASM'.

 

Quote

Okay, found a version here:

That's the .lib file, not a dll. Please use the DLL from the zip file above.

To use the dll to your project in Visual Studio:

In Visual Studio you can add this DLL to your project as a normal project item and set the property "Copy to Output Directory" to "Copy if Newer".

 

Quote

Do you support Read/Write Lvar in FSUIPCClient v3.2.8 out of the box

Yes, FSUIPC7 now supports this legacy method of reading and writing LVARS. It was designed back in the days of FSX and is provided now so that old applications using FSUIPC will now work on MSFS.

You can use this feature if you like (it's a bit easier) but it's significantly slower than using the new MSFSVariableServices. Each LVAR read/write takes up a whole IPC exchange to itself. If you're accessing 10 variables this might be okay. If you want to read 30 or more in real time, this method is going to be too slow. 

Paul

Link to comment
Share on other sites

Quote

You can use this feature if you like (it's a bit easier) but it's significantly slower than using the new MSFSVariableServices. Each LVAR read/write takes up a whole IPC exchange to itself.

My system is pretty fast, I'll bench mark it.

As for using MSFSVariableServices, only issue I have is with the window handle. I am using your library inside my library and I have no access to the Window handle. I could pass it to the library as parameter but some code is structured in a way that I cannot pass it as a parameter. The only option I think I have is:

 

System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle

I still have to test this if it will work. Can you abstract away the requirement of window handle?

 

2)

On another note, I tried to use your library with FSUIPC/WASM that allows users to map free offsets to Lvars. This mapping is done in the .ini of FSUIPC like this:

[LvarOffsets.crj]
1=L:ASCRJ_FCP_HDG=SD0xA000

Then I created an offset (0xA000) of the specific data type and wrote a value into it and called Process function but nothing happened. I could never get it to work. Everything from FSUIPC/WASM is correctly setup/installed. I knew I was writing some memory location because the value was retained after reading it back but the actual lvar was not changed since in the Sim the CRJ lvar was not affected. Any comments on this?

 

3)

When I use the "MSFSVariableServices" class and I perform Start(), Stop() and then Start() again I receive the following, repeating log entry:

My log is configured to trace all messages (_lvarSvc.LogLevel = LOGLEVEL.ENABLE_LOG;)

Lvars log:  [TRACE]: Config data requested...

 

What does that mean? Is this a problem? It only happens if I start/stop/start again the MSFSVariableServices class.

 

4) I sometimes also receive the following exception when starting MSFSVariableServices , this seems to happen after I close and launch my C# app again (2nd launch). Then goes away, then comes back.

Exception thrown at 0x00007FFA8FD7722C (FSUIPC_WAPID.dll) in GoFlightClientApp.exe: 0xC0000005: Access violation reading location 0x00000274C9CC3C78.

Here's my initialization code, it resides in ctor of a singleton class inside a DLL. I am using GetCurrentProcess().MainWIndowHandle to obtain the handle.

The start(), stop() invocations are in Connect(), Disconnect() wrappers of my singleton class.

_LvarsSvc.LogLevel = LOGLEVEL.ENABLE_LOG;
_LvarsSvc.OnLogEntryReceived += Lvars_OnLogEntryReceived;
_LvarsSvc.OnVariablesReadyChanged += Lvars_VariablesReadyChanged;
_LvarsSvc.OnValuesChanged += Lvars_OnValuesChanged;
var hWindow = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
_LvarsSvc.Init(hWindow);
_LvarsSvc.LVARUpdateFrequency = 10; // Get new lvar values 10 times per second (Hz)

 

Link to comment
Share on other sites

Quote

 and I have no access to the Window handle.

I don't think it actually uses it to access your window. I think it's just a unique ID that the WASM module uses to keep the requests from multiple clients separated. You can probably just create an IntPtr from a random Int32 value and pass that instead.   

Quote

Can you abstract away the requirement of window handle?

Yes, if the random pointer works I could add a constructor without the handle parameter and make a random ID inside the dll.

Quote

the actual lvar was not changed since in the Sim the CRJ lvar was not affected.

[LvarOffsets.crj]
1=L:ASCRJ_FCP_HDG=SD0xA000

SD is signed double word which in C# would be a normal 4 byte 'int'. So check your A000 offset is declared as 'int'. 

If you don't mean to be working with a c# int you'll need to change SD to the appropriate size:

c#     -> size in ini file

sbyte  -> SB
byte   -> UB
short  -> SW
ushort -> UW
int    -> SD
uint   -> UD
double -> do not specify a size.

Paul

Link to comment
Share on other sites

Quote

Exception thrown at 0x00007FFA8FD7722C (FSUIPC_WAPID.dll) 

If the exception is thrown by the FSUIPC_WAPID.dll then you need to ask John about that as it's his dll.

Quote

Lvars log:  [TRACE]: Config data requested...

Same here. The log messages are produced by John's WASM module so I couldn't tell you what this means or if its a problem or not.

Paul

Link to comment
Share on other sites

Quote

SD is signed double word which in C# would be a normal 4 byte 'int'. So check your A000 offset is declared as 'int'. 

Yes, I know, I have verified that my data types match in the ini with the datatype of the offset object (I tried using UB (byte) and SD (int), no luck). I asked John, and he mentioned in his last response that I need a registered version for this functionality (which I don't have). I am waiting for confirmation on this from him.

I'll try your suggestions with the Window handle.

Link to comment
Share on other sites

@kingm56

@activex

Version 3.2.9 BETA is now on NuGet. (Tick 'Include Prerelease' to see it).

This might fix the access violation problems. I've changed the way the incoming strings are handles from the C dll. It was technically wrong before so I'm hoping this will fix the problems.

Also there are new overloads for Init() so you don't need to pass a window handle. The DLL will handle this internally.

Paul

Link to comment
Share on other sites

Quote

This might fix the access violation problems. I've changed the way the incoming strings are handles from the C dll. It was technically wrong before so I'm hoping this will fix the problems.

So I did some testing on my end and so far so good, 0 crashes 🙂

 

  • Like 1
Link to comment
Share on other sites

Hi Paul,

I got temp license for FSUIPC and tried using the "offset to lvar" mapping functionality (via WASM) and it still doesn't work (ie. No exceptions, but nothing happens). Setting the offset 0xA000 to "1" should toggle hdg mode in the CRJ (by Aerosoft). Any ideas? What am I missing??

Interestingly, when I do use the Set Lvar (under WASM in FSUIPC) option and set the ASCRJ_FCP_HDG to 1, it toggles the hdg mode. This also works using your api via FSUIPCConnection.WriteLVar("ASCRJ_FCP_HDG", 1);. I know you may not have the CRJ, but can you try this using FBW airbus and try to toggle one of their lvars?

Here's a simple test:

FSUIPC7.ini

[LvarOffsets.crj]
1=L:ASCRJ_FCP_HDG=UB0xA000

 

class Program
	{
		static void Main(string[] args)
		{
			try
			{
				FSUIPCConnection.Open();
				var offset = new Offset<byte>(0xA000);
				offset.Value = 1;

				FSUIPCConnection.Process();
			}
			catch (Exception ex)
			{
				Console.WriteLine($"*** ERROR: {ex}");
			}
			finally
			{
				FSUIPCConnection.Close();
			}
		}
	}

 

Link to comment
Share on other sites

I can't test this myself as I don't own MSFS. 

Your c# code looks fine. I don't think the problem is there.

I notice you're using a profile called crj. Are you sure you've set this up properly in FSUIPC? Are you sure it's being used (active)?

You could try it without using profiles - just change the section to be global:

[LvarOffsets]
1=L:ASCRJ_FCP_HDG=UB0xA000

If that works then your crj profile isn't set up properly or isn't being activated.

If it still doesn't work then John is really the person to help you on this. If you show him your full fsuipc.ini file he might be able to spot the problem.

It's working via all the other code methods so the problem will be somewhere in your FSUIPC configuration.

Paul

Link to comment
Share on other sites

Quote

You could try it without using profiles - just change the section to be global:

That resolved the issue (I guess I misread the FSUIPC documentation or don't understand it very well), now I can toggle the hdg mode. To toggle hdg mode, I have to set Lvar to 1 and then reset it back to 0 so I can toggle it next time (I verified this within the sim by looking at the Lvar). But, to get this working properly I had to insert a thread sleep between setting the value and clearing the value, see code below.

My question is: Do you know why this is? Out of curiosity, when I set the Lvar with your api call:

FSUIPCConnection.WriteLVar("ASCRJ_FCP_HDG", 1);

do you add an explicit delay or in your case is the time it takes to make an IPC call sufficient of a delay for it to work?

 

Code re-written to toggle the hdg mode, works all the time now.

static void Main(string[] args)
		{
			try
			{
				FSUIPCConnection.Open();
				var offset = new Offset<byte>(0xA000);
				offset.Value = (byte)1;

				FSUIPCConnection.Process();

				System.Threading.Thread.Sleep(10);
				
				offset.Value = 0;
				FSUIPCConnection.Process();

				//FSUIPCConnection.WriteLVar("ASCRJ_FCP_HDG", 1);
			}
			catch (Exception ex)
			{
				Console.WriteLine($"*** ERROR: {ex}");
			}
			finally
			{
				FSUIPCConnection.Close();
			}
		}

 

Link to comment
Share on other sites

Quote

1) Reset the offset back to 0 after setting it to 1 previously to initiate the toggle.

Yes, normally offset values are read from the sim when you call Process(). They only write if the value has changed. So setting the value to 1 when you have previously set the value to 1 won't trigger the write.

Your code would be fine if the LVar took an explicit value for each state (which is usually the case), but since it's toggling with a 1 you'll need to use a write-only offset. These write on every process() even if their value has not changed. Because of this it's advisable to put them in their own group so you can control when they are written.

var offset = new Offset<byte>("ToggleHeading", 0xA000, true); // write only

Then your code will only need this:

offset.Value = (byte)1;
FSUIPCConnection.Process("ToggleHeading");


 

Quote

 

Out of curiosity, when I set the Lvar with your api call:

FSUIPCConnection.WriteLVar("ASCRJ_FCP_HDG", 1);

do you clear the offset after?

 

This uses a special offset that instructs FSUIPC to send the LVAR value. It's write only and clears itself internally after each request. So every time you call this method the Lvar gets written regardless of the previous value.

Paul

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.