doia Posted May 26, 2010 Report Posted May 26, 2010 Hi, I am writing a program to acquire FSX parameters using FSUIPC in C. I am having a hard time acquiring some values- all they seem to return is zero. Examples of parameters that return zero every time: 11C6, 11D0, 31E4, 0609 Examples of parameters that return the correct value: 0240, 3060, 6020 I am using the same code for every parameter acquired: double sim_value =0; FSUIPC_Read(param_offset, param_bytes, &sim_value, &dwResult); My guess is that I am getting zeros because I am trying to acquire everything as a double and passing FSUIPC_Read incorrect data types for the third parameter. Can anyone please explain how I should about acquiring all values using a generic code? If it's not possible to use a generic code then how do I know the correct data type to pass on to the function?
Pete Dowson Posted May 27, 2010 Report Posted May 27, 2010 I am using the same code for every parameter acquired: double sim_value =0; FSUIPC_Read(param_offset, param_bytes, &sim_value, &dwResult); My guess is that I am getting zeros because I am trying to acquire everything as a double and passing FSUIPC_Read incorrect data types for the third parameter. The third parameter is merely a pointer to an array of bytes to receive the data. Their is no type for the data exchange as such. The type is set by the way you read it. Strings have to be read into strings or character arrays, integers into integers, and so on. The "double" floating point reception you are giving everything is completely wrong for nearly everything available in the FSUIPC interface. Only those entries which are 8-bytes in length AND which are specifically documented as being a double or floating point are in this format. Can anyone please explain how I should about acquiring all values using a generic code? If it's not possible to use a generic code then how do I know the correct data type to pass on to the function? As I said, you don't pass any types to the function, only a pointer to a receptacle, an area of memory to receive any sort of data. If you want generic code you could define a union to hold all types in one place, thus: union { double d; __int64 n8; BYTE b; signed char ch; WORD w; signed short s; DWORD dw; int n; char str[256]; } genericvalue; FSUIPC_Read(param_offset, param_bytes, &genericvalue.b, &dwResult); Then access whichever member of the union is appropriate to the value. Please remember, however, that it is extremely inefficient to do lots of FSUIPC_Process calls. You should do all of the reads and writes and then one process call per cycle. The reads and writes merely build up the request list, but the process sends messages to FS and has to do a process switch. If you are doing a generic read into one location, you can obviously only do one per process. That's too inefficient. You'll slow your program down and FS. You'd need to define a different location for each read, so defeating the "generic" option you seem so keen on achieving. Regards Pete
doia Posted May 27, 2010 Author Report Posted May 27, 2010 Pete, Sorry for my confusion and thank you for the help. Perhaps I can allocate memory inside an array of elements and have FSUIPC_Read store the value in a different element of that array each time it is called inside a loop - this way I can have a rather generic call and limit the amount of FSUIPC_Process calls by using it only after a certain number of read requests. I currently have my program look up a table to find the corresponding FSUIPC offset and byte size. My second idea would be to add a "flag" to each parameter in the table that would guide the program in calling the appropriate data receptacle. The call would not be exactly generic but this seems like a fairly simple solution.
Pete Dowson Posted May 27, 2010 Report Posted May 27, 2010 Perhaps I can allocate memory inside an array of elements and have FSUIPC_Read store the value in a different element of that array each time it is called inside a loop If you wish, but this is really what the FSUIPC_Read procedure is doing internally in any case. Why bother? You are replacing one call to FSUIPC_Read, to get your value into a variable you can use directly, by a call with parameters into another procedure of your own which is then doing the FSUIPC_Read, and, on exit, following the FSUIPC_Process, you still have to access the correct type in the correct element of your array in order to use the values. It seems a rather inefficient and long-winded way of doing something which was deliberately made simple by the library provision of the FSUIPC_Read, Write and Process calls in the first place. If you simply don't like the mechanism provided for you why not interface directly to FSUIPC, not using the library calls at all? The library source is provided in the SDK so you completely at liberty to do as you like at a lower level. this way I can have a rather generic call and limit the amount of FSUIPC_Process calls by using it only after a certain number of read requests. The Process call should be once per cycle, not "after a certain number of read requests", unless you are talking about building up requests involving more than 30 kbytes! You should be basing your actions on a polling cycle like 20 - 100 mSecs, or longer is you don't need such resolution. Regards Pete
doia Posted May 27, 2010 Author Report Posted May 27, 2010 If you wish, but this is really what the FSUIPC_Read procedure is doing internally in any case. Why bother? Well you pointed out earlier that in order to actually store the parameters into the allocated memory I need to run the FSUIPC_Process call after my FSUIPC_Read requests. You also pointed out that it is highly undesirable to make multiple Process calls as it slows down FS and FSUIPC. I am no expert programmer and I understand my scope of resources in C is quite limited but I thought that having an array would be the easiest way to allow me to do those multiple read requests, defining a different memory location for each read request in a semi-automated fashion. It would allow me to have a generic acquisition code without the need to do multiple Process calls. I will post my results here. Thank you for all your help and for clarifying everything Pete. Regards, Isadora
Pete Dowson Posted May 27, 2010 Report Posted May 27, 2010 I am no expert programmer and I understand my scope of resources in C is quite limited ErC is probably the most powerful high-level programming language in terms of scope and flexibility, so I don't really know where you are coming from with that statement. I started with assembly language (well machine code originally) and C is about as "high" as I want to get because I find other languages definitely limited in comparison. ... but I thought that having an array would be the easiest way to allow me to do those multiple read requests, defining a different memory location for each read request in a semi-automated fashion. It would allow me to have a generic acquisition code without the need to do multiple Process calls. But a long list of calls to a "generic read" procedure, followed by a Process call, then a long list of extractions of variables with specific types, seems much more cumbersome than a simple list of FSUIPC_Reads into the correct variables in the first place, followed by one Process call, and you are done! You seem to be wanting to make it complex and long-winded for some reason I don't understand. As I said, if you want to engineer your own style of interface, do please look at the source code for the library calls. They build up the requests in an irregular array as it is. If you want to go down that route you can bypass the FSUIPC_Reads and Writes and build the data structures yourself. Just make sure they follow the rules you'll see implemented there. If you are simply trying to make something data- or table-driven, possibly with parameters like offset, size and type specified by external data input, then I can see where you are coming from. But you'll need some sort of data type code and use that on a switch both for data length and variable receptor type. This is basically how FSinterrogate works -- I assume you've played with that? It is in the SDK. It was written in Delphi by Pelle Liljental. Regards Pete
doia Posted May 27, 2010 Author Report Posted May 27, 2010 If you are simply trying to make something data- or table-driven, possibly with parameters like offset, size and type specified by external data input, then I can see where you are coming from. But you'll need some sort of data type code and use that on a switch both for data length and variable receptor type. That is exactly what I would like to do. I have already implemented data length but the variable receptor type is what I was having problems with. I had briefly looked at FSInterrogate before but now that I am actually reading the manual I can see it will save me a lot of work. Thank you again Pete! Best Regards, Isadora
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now