Jump to content
The simFlight Network Forums

Problem in cosing C++


Recommended Posts

Hello,

I am programming an interface of FSUIPC to the Tcl language. I have it working and basically I simply map the Open/Read/Write/Close functions to make them available on Tcl.

My question is actually Tcl-independent. I'm having trouble reading some values at some times. For instance, the heading value (0x580) reads the correct value most of the times but some times I cannot seem to get a correct value. For example, if the memory holds the decimal value 916312602 (which corresponds to heading 76) I cannot seem to read it correctly.

My "read" function receives as parameters the offset and the number of bytes to read.

Here is my code:

  DWORD dwResult, offset, bytecount;
  void *data;

// offset is sent as a parameter, in this case 0x580
// bytecount is sent as a parameter, in this case 4 for heading

	if (!FSUIPC_Read(offset, bytecount, data, &dwResult) ||
				// If we wanted other reads/writes at the same time, we could put them here
				!FSUIPC_Process(&dwResult)) {
		sprintf_s(err, "FSUIPC: Failed to read from link: %s", pszErrors[dwResult]);
		// RETURN ERROR
	}

        // RETURN valid data

Now the above code has been tested with many other variables. IAS also has this problem from time to time. But vertical speed for instance is always correct. Notice that I have confirmed that the problem is not when the value is returned to Tcl. Right after the FSUIPC_Read call, the value stored in data is incorrect.

I tried programming it a different way and it seems to work correctly, although I didn't want to use this method:

  long val;
	if (!FSUIPC_Read(offset, 4, &val, &dwResult) || ....

i.e., if I send a pointer to a long value, then it is obtained correctly.

Another thing I tried was using "char * / char []" instead of "void *" for data. Problem remains. Tried also using "memset" to set all bits to 0. No good here either.

Can someone point me out to what the problem is?

Thanks,

Miguel

Link to comment
Share on other sites

i.e., if I send a pointer to a long value, then it is obtained correctly.

What are you normally sending a pointer to, then? Obviously that's where your problem lies -- in your consequent interpretation of the data due to using the wrong data type.

Doesn't this "Tcl" have a debugger you can use? when the fault is in your own code that's usually the best way to locate it.

Another thing I tried was using "char * / char []" instead of "void *" for data. Problem remains.

You should always use the correct type for the value concerned. The heading is actually an unsigned 32-bit integer, so "unsigned int" (in C) would be correct. If you are interpreting it in any other way you are going to see wrong values.

It is nothing to do with how the interface works. As far as FSUIPC is concerned all the data in all the offsets is just in single bytes, and you are reading an array of bytes of the length you request. But your code MUST interpret them in the correct way for their contents. The data isn't different (there's no way it can be!), it's how you are treating it.

Regards

Pete

Link to comment
Share on other sites

Hello Pete,

Thanks for your reply. I've tested the code with consecutive calls. Let me try to explain it for the "heading":

function FSUIPCREAD(...,   int offset,   int numberofbytes,   ....) {
  void *data;

  data=malloc(numberofbytes);  // allocate 4 bytes in this case
  memset(data, 0, numberofbytes);    // to make sure everything is clean
  FSUIPC_Read(offset, numberofbytes, data, &dwResult);     // offset = 0x580

  Tcl_SetResult(..., (char *) data,...);   // this interfaces with Tcl and returns the value
}

Therefore, the "heading" is read and stored into "data" which has been initialized for 4 bytes. Tcl_SetResult is a function that returns the data to Tcl. However, whenever the problem occurs, I already have "data" with an incorrect value prior to returning it to Tcl.

If I do the following cycle in Tcl (pseudo code below):

while { forever } {
  val  =  Call_FSUIPCREAD_from_C  0x0580  4   ; // read 4 bytes from offset 0x580 (heading)
  val = $val * 360 / (65536*65536)            ; // calculate heading
  write($val)                                 ; // output to screen
}

It ends up doing something like this:

34

34

34

34

0

34

34

34

34

0

34

34

.......

Most of the times it reads the value well. When it doesn't, it reads as "0", or "1" or a low value. I found out why: when the result is incorrect, it is because the value returned is 1 byte misaligned. If I split the "heading" value that has been read, into hex components:

0x4BDEF017 => 0x4B 0xDE 0xF0 0x17 => 75 222 240 23

But, when the problem occurs, I see something like: 1582 240 23 0 (notice that 240 is now byte #2 and 23 is now byte #3) and a 0 appears.

My doubt here is: why does this happen some times, in a non-deterministic way? I thought that using a "void *" in C would enable me to map the FSUipc_Read function to Tcl in a generic form, rather than having to create a function for each value I want to retrieve, depending on byte sizes, etc.

Miguel

Link to comment
Share on other sites

Therefore, the "heading" is read and stored into "data" which has been initialized for 4 bytes. Tcl_SetResult is a function that returns the data to Tcl. However, whenever the problem occurs, I already have "data" with an incorrect value prior to returning it to Tcl.

You have an error then. There is absolutely no other explanation. You need to use a debugger and work out what you are doing wrong.

Sorry, I really cannot help you debug your code, especially stuff which makes no sense to me whatsoever. I can't even see where you are calling FSUIPC_Process to call FSUIPC. If your FSUIPC_Read is the one I supply in the library, then all that does is put your request into a queue in the shared memory-mapped file area.

Regards

Pete

Link to comment
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
×
×
  • 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.