Sign in to follow this  
n4gix

C gauge issue

Recommended Posts

Ok, I'm having a problem.I've got a rather complex gauge I'm coding in VC++ 6. In order to ensure I don't get 'lost' in the code I've split out sections into separate .c files. Each one has it's own header file to declare any variables they offer as well as reveal functions that need to be accessable from the base gauge code.However, the gauges.h file is giving me fits.To ensure I can declare MODULE_VAR variables and other variable types defined in gauges.h, I need to add #include to the individual header and code files.As example, say I have a base gauge called b767DADC. It's main file is b767DADC.c. That file has all the common gauge declarations contained in it, and at the top references the #include so that everything is 'known'.Now, say I have a section of code that deals with power distribution... let's call it powercode.h and powercode.c for arguments sake.In powercode.h are the variables and functions declared like:extern UINT32 power_avail;void init_power();Because UINT32 is defined in gauges.h the first line in powercode.h has to be #include Now, in powercode.c the actual variable and function exist:UINT32 power_avail;void init_power(){ // do something}Once again, at the top of powercode.c is #include so that the gauge specific defines and structures (etc) are 'known'.When I compile, I get this error:_get_listelement_pointer@8 already defined in b767DADC.objApparently, either I'm a total idiot... or I'm a total idiot. How do I accomplish this? This gauge is far to large and complex in code size to write it all into a single file.

Share this post


Link to post
Share on other sites
Help AVSIM continue to serve you!
Please donate today!

Don't #include gauges.h in each of the sub-gauge .h files.Instead, #include master.h file...

Share this post


Link to post
Share on other sites

I'm not quite following..master.h??I have:b767DADC.hb767DADC.cpowercode.hpowercode.cAs file examples.... since I know you're well aware of the way EG makes the base files for a gauge, I won't go into tons of detail. Suffice it to say I need to make it so I can write out separate sections of code into sepearate .c files with corresponding .h files so that I can compartmentalize the code for clarity's sake.The part that's not going well is the EXTERN_C declarations in the gauges.h file.

Share this post


Link to post
Share on other sites

>I'm not quite following..>>master.h??>>I have:>b767DADC.h>b767DADC.c>powercode.h>powercode.c>>As file examples.... since I know you're well aware of the way>EG makes the base files for a gauge, I won't go into tons of>detail. Suffice it to say I need to make it so I can write>out separate sections of code into sepearate .c files with>corresponding .h files so that I can compartmentalize the code>for clarity's sake.OK, so you want to make a multi-gauge. See my tutorial at http://flightsim.com in the Panels & Gauges forum for details on how to convert EG source files into a multi-gauge project.It isn't difficult at all, but it does require that certain things be done, in the correct order. I've provide a fully illustrated example along with step-by-step instructions... ;)Essentially though, you will be creating a "master.c" file along with a "master.h" and "master.rc" file into which all global information is placed.This collection of "master" files will tie all the sub-gauges together.

Share this post


Link to post
Share on other sites

>I have:>b767DADC.h>b767DADC.c>powercode.h>powercode.cWhen you are finished reworking the code per my tutorial, you will have:b767.cb767.hb767.rcas "master files" The others will be 'subgauge' files:b767DADC.hb767DADC.cpowercode.hpowercode.c

Share this post


Link to post
Share on other sites

Um... sorry, I'm not trying to make a multi-gauge.Lemme try again.I have the basic files generated by EG.b767DADC.hb767DADC.cb767DADC.rcb767DADCG.cNow, this gauge is a non-visual gauge... but it's a whole lot of 'brains', per se.As example, it is responsible for:1) Power Systems2) IRU Systems3) Air Data Systems (airspeed etc)4) Cabin Pressurization SystemsJust to name a few.Now, as you know the gauges.h file is declared in the b767DADC.h file. The b767DADCG.c file is added via an #include "b767DADCG.c" entry in the b767DADC.c file.Let's say for the power I have two files:powercode.h - declares all variables defined by the power systems as well as functions to be called from within b767DADCG.c.powercode.c - holds all the actual variables as well as any functions for the power systems.In the powercode.h file a variable would look like:extern UINT32 power_avail;In the powercode.c file it would be:UINT32 power_avail = 0;Now... all of this works fine... what causes the problem is that the UINT32 is defined in the gauges.h file. As well, there's a need to be able to call functions like lookup_var(). Because of that, powercode.c MUST have #include at the top of the file. This means gauges.h is referenced more than once within the entire project, which in C is actually perfectly acceptable (there's an #ifndef that makes it safe). What's causing the problem is three declarations:EXTERN_C PELEMENT_HEADER FSAPI get_listelement_pointer(PELEMENT_HEADER pelement,UINT32 pos_element);EXTERN_C void FSAPI add_imagedata_to_listelement(PELEMENT_HEADER pelement,UINT32 pos_element,FLAGS image_flags);EXTERN_C void FSAPI remove_imagedata_from_listelement(PELEMENT_HEADER pelement,UINT32 pos_element,FLAGS image_flags);The compiler sees these as being redeclared and doesn't like it much, refusing to actually compile the gauge because of it.So... I have to find out how to eliminate this problem.

Share this post


Link to post
Share on other sites

>Um... sorry, I'm not trying to make a multi-gauge.>>Lemme try again.>>I have the basic files generated by EG.>>b767DADC.h>b767DADC.c>b767DADC.rc>b767DADCG.c>Now, as you know the gauges.h file is declared in the>b767DADC.h file. The b767DADCG.c file is added via an>#include "b767DADCG.c" entry in the b767DADC.c file.>powercode.h - declares all variables defined by the power>systems as well as functions to be called from within>b767DADCG.c.Then use #include powercode.h in the b767ADC.h file.>powercode.c - holds all the actual variables as well as any>functions for the power systems.#include powercode.c in the b767ADCG.c file.

Share this post


Link to post
Share on other sites

Ok... powercode.h has the fuctions defined inside the powercode.c file. It declares them so that any code that includes the powercode.h file can 'see' the functions and variables that are in powercode.c.The #include for powercode.c would end up causing a duplicate definition for both the variables AND the functions in powercode.c.The entire point of creating powercode.h as a separate file is so you can use the code and variables inside powercode.c without doing a physical #include.It's much like creating a .lib file and using the .lib file's header to gain access to all the .lib file provides.The problem appears to be in the gauges.h file... and I can't get past that.

Share this post


Link to post
Share on other sites

No, the problem is that you have seem to have two .c files with precisely the same information at the top, something like this:char rtu_gauge_name[] = GAUGE_NAME;extern PELEMENT_HEADER rtu_list;extern MOUSERECT rtu_rect[];GAUGE_CALLBACK rtuCallBack;GAUGE_HEADER_FS700(GAUGE_W, rtu_gauge_name, &rtu_list, rtu_rect, rtuCallBack, 0, 0, 0);remove all the above and replace it with:#include powercode.hSomewhere within the gauge scope of your b767DADC.c file:#include powercode.cFlag powercode.c to be "Exclude from Build" to eliminate the problem with redefinitions.Of course, the easier way would be to simply let powercode.c compile as a separate 'invisible gauge.' ;) They'll still talk to each other as long as they are in the same multigauge cluster...

Share this post


Link to post
Share on other sites

It would be wonderful to say you're right... but...I have exactly one place where that section of code exists, within the b767DADCG.c file only.The file powercode.c has absolutely NO gauge within it. It is simply a section of code that is responsible for monitoring MSFS power variables and deciding if the plane's power systems are working or not. Based on it's own functions it sets values for broadcast variables declared in the powercode.h file. It has to reference the gauges.h file to 'know' what a UINT32 is as well as a MODULE_VAR and be able to call functions such as lookup_var();The reason for separating all of this out isn't to create a multi-gauge... it's to simplify the coding. If it weren't spread out, it would be one singly HUGE .c file.

Share this post


Link to post
Share on other sites

>It would be wonderful to say you're right... but...>The reason for separating all of this out isn't to create a>multi-gauge... it's to simplify the coding. If it weren't>spread out, it would be one singly HUGE .c file.I know exactly what you're describing, Ed. I have a PFD that has many of the complex elements "broken out" into multiple .cpp and .h files as well.The main gauge .c file contains the call to the citationxl.h file:#include #include "fs9gauges.h"#include "fsvars.h"#include "citationxl.h"#include "BCD.h"ULONG_PTR gdiplusToken;#include "gdi_s_sh.h"#include "PFD_functions.cpp"/////////////////////////////////////////////////////////////////////////////// PFD/////////////////////////////////////////////////////////////////////////////#define GAUGE_NAME "Citation XLS PFD"#define GAUGEHDR_VAR_NAME gaugehdr_pfd#define GAUGE_W 100#include "citationxl.pfd.cpp"/////////////////////////////The #include in the last line calls "citationxl.pfd.cpp" which has:#include #include "cxl.pfd.h"char pfd_gauge_name[] = GAUGE_NAME;extern PELEMENT_HEADER pfd_list;extern MOUSERECT pfd_rect[];GAUGE_CALLBACK PFDCallBack;using namespace Gdiplus;PIXPOINT dim;cxlpfd cxpfd;HDC hdc;BOOL nodraw = 0;BOOL msglp = 0;GAUGE_HEADER_FS700(GAUGE_W, pfd_gauge_name, &pfd_list, pfd_rect, PFDCallBack, 0, 0, 0);/////////////////////////////The second line above calls the cxpfd.h file, which has this at the end:#include "cxl.pfd.cpp"This 'chains' to the main PFD drawing code:#include "airspeed.cpp"#include "vsi.cpp"#include "attitude.cpp"#include "altitude.cpp"#include #include "hsi.cpp"using namespace Gdiplus;cxlpfd::cxlpfd(){///////////////////////////////////////Note that the actual "drawing code" is broken out into FIVE separate .cpp files, each of which has its own .h file! ;)Ed, it's simply a matter of "chaining" the various #include(s) in the correct order... ;)

Share this post


Link to post
Share on other sites

>I've got a rather complex gauge I'm coding in VC++ 6. In>order to ensure I don't get 'lost' in the code I've split out>sections into separate .c files. Each one has it's own header>file to declare any variables they offer as well as reveal>functions that need to be accessable from the base gauge>code.This is fine. Each .h is used for declarations in the related .c file.One thing you are likely missing is that you need to make sure that you have an #include 'guard' like:#pragma once // MS compilersor#ifndef _MyHeader#define _MyHeader// Code goes here.#endif>However, the gauges.h file is giving me fits.>>To ensure I can declare MODULE_VAR variables and other>variable types defined in gauges.h, I need to add #include> to the individual header and code files.Actually, you should not do this. The purpose of putting declarations into a .h file is to make it possible to make those declarations visible without manually re-entering forward declarations in .c files each time you need them.You can include gauge.h in the .c file directly, or in its related .h file, which when included in the .c file will do the same thing, but no need to do both.With the aforementioned #include guard it won't matter if you put it in the .h file, so that's where I'd put it.>As example, say I have a base gauge called b767DADC. It's>main file is b767DADC.c. That file has all the common gauge>declarations contained in it, and at the top references the>#include so that everything is 'known'.Technically, gauges.h is a 'user' header, and as such should be put in your own /inc directory and you should be using this syntax:#include "gauge.h"What I recommend is under your "Projects" directory creating a 'standard' include directory (most of us C guys call it ./inc), and then make sure you add it to the directories to search on the project properties. Then, in the future, you can put any SDK .h 's there and have them available to all projects. But, you can do what you are doing if you have gauges.h in the right directory even if it is technically wrong.>Now, say I have a section of code that deals with power>distribution... let's call it powercode.h and powercode.c for>arguments sake.>>In powercode.h are the variables and functions declared like:>>extern UINT32 power_avail;>>void init_power();>>Because UINT32 is defined in gauges.h the first line in>powercode.h has to be #include Nothing wrong with this. But remember your #include guards!>Now, in powercode.c the actual variable and function exist:>>UINT32 power_avail;>>void init_power()>{> // do something>}>>Once again, at the top of powercode.c is #include >so that the gauge specific defines and structures (etc) are>'known'.Again, this #include is not needed as it is already included via the .h file.>When I compile, I get this error:>>_get_listelement_pointer@8 already defined in b767DADC.obj>>Apparently, either I'm a total idiot... or I'm a total idiot. >How do I accomplish this? This gauge is far to large and>complex in code size to write it all into a single file.This error means that you are not using the #include guards, and a subsequent inclusion is attempting to re-define something.Also, you will find that there can be order issues in #includes, so be careful.Good luck.

Share this post


Link to post
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
Sign in to follow this