Thread: Public

  1. #1
    Registered User
    Join Date
    Jul 2003
    Posts
    32

    Public

    Hello world.
    How can I make a struct declaration in a C++ source file public? (for use in another C++ source file within the same Win32 DLL project)

  2. #2
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    Declare it in a header file that is #included by both source files.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  3. #3
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    To elaborate on what benny just said... have your header file look like this

    Code:
    #ifndef structheader
    #define structheader
    
    /* struct definition goes here */
    
    #endif
    This avoids the problem of the file being included multiple times.
    Away.

  4. #4
    Registered User
    Join Date
    Jul 2003
    Posts
    32
    Yeah, I figured that out but there's one little problem left ... I was exporting functions from those source files. Since I changed them into headers the functions no longer get exported - I get "unresolved definitions" or smth like that.
    Is it possible to export from .h files (using *.DEF)?

  5. #5
    Confused
    Join Date
    Nov 2002
    Location
    Warwick, UK
    Posts
    209
    What do the #ifndef, #define and #endif declarations do ?

  6. #6
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    Helix, do you mean to say that you placed your function definitions in a header file? Only funtion PROTOTYPES should be in header files. The actual functions should be in the source files.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  7. #7
    Grammar Police HybridM's Avatar
    Join Date
    Jan 2003
    Posts
    355
    Korhedron, What they do specifically is, the compiler checks to see if structheader is defined, if it is, then that means the file has been included once already, if structheader is not defined, then the compiler defines it, and includes the stuff in that header.
    Thor's self help tip:
    Maybe a neighbor is tossing leaf clippings on your lawn, looking at your woman, or harboring desires regarding your longboat. You enslave his children, set his house on fire. He shall not bother you again.

    OS: Windows XP
    Compiler: MSVC

  8. #8
    Confused
    Join Date
    Nov 2002
    Location
    Warwick, UK
    Posts
    209
    STRUCTHEADER, in this case, being a .h file ? Why not include it using #include ?

  9. #9
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    Korhedron, HybridM is referring to the method of using preprocessor commands to prevent multiple declarations, ie, errors.

    Eg:

    You have two source files. Each one #includes the same header file, blah.h.
    If the compiler runs the header file code twice, the same structures, classes, functions, etcetera, will be declared twice. So, these commands are inserted in the header file to ensure that it will only be run once.

    Code:
    #ifndef thisHeader //if this header isn't run yet
    #define thisHeader //then define it as being run
    
    //declare all your stuff here
    
    #endif
    Note that thisHeader can be any unique name.

    What happens is, the first time the header is included, the name thisHeader is not defined. Therefore, the name is defined, and all of the structures etc are declared. The next time the header is included, and all subsequent times, it skips everything and goes right to the #endif line.

    It's a very good way to organise your code if you have more than one source file.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  10. #10
    Confused
    Join Date
    Nov 2002
    Location
    Warwick, UK
    Posts
    209
    I'm not seeing how you'd declare something twice except if you have three sources, in which you include one code, then include that one and the first one in the third code... :P Example :

    Code:
    // header1.h
    void blabla();
    Code:
    // header2.h
    #include "header1.h"
    void afunction();
    Code:
    // header3.h
    #include "header2.h"
    #include "header1.h"
    codehere();

    This would mean that header1.h is included twice. Is this what you mean ?

  11. #11
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    No Korhedron, I mean exactly what I said in my post:

    You have two source files. Each one #includes the same header file, blah.h.
    A source file is a .cpp.

    Eg:

    Code:
    //main.cpp
    #include "main.h"
    
    int main()
    {
    }
    Code:
    //clsTree.cpp
    #include "clsTree.h"
    #include "main.h"
    class clsTree
    {
    };
    Code:
    //main.h
    #ifndef mainHeader
    #define mainHeader
    
    int main();
    LRESULT CALLBACK WndProc();
    
    #endif
    You see what I'm getting at? Both source files (main.cpp and clsTree.cpp) include main.h. Without any preprocessor commands (#ifndef, #endif, #define), all the declarations in main.h would be run twice. With the preprocessor commands in, it can only be run once per compile. Brilliant ey?
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  12. #12
    *******argv[] - hu? darksaidin's Avatar
    Join Date
    Jul 2003
    Posts
    314
    Without any preprocessor commands (#ifndef, #endif, #define), all the declarations in main.h would be run twice. With the preprocessor commands in, it can only be run once per compile. Brilliant ey?
    To me it always seemed like nothing more than a workaround for a compiler misconception. However, I admit that my opinion may be a bit biased since I never had to use headers. I think they are a pain.


    edit: thanks cat
    Last edited by darksaidin; 07-27-2003 at 05:10 PM.

  13. #13
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Actually, bennyandthejets, that's half true but you're still mistaken. Each .cpp file is a separate compilation unit -- main.h will be put within main.cpp when main.cpp compiles, but this will happen only once. main.h will also be put into clsTree.cpp when it compiles, but again not more than once.

    If duplicate symbols arise that are identically defined, it's the linker's job to merge them. In this case, main.h probably has only function declarations and class definitions, which could be included in other compilation units without a problem anyway. In that one case, the include guards do nothing.

    Korhedron, that scenario happens a lot more than you'd think. For example, I was working on a library recently, and most of the headers include headers defining LibObject and LibException, so include guards are critical. And, in any event, your code shouldn't break if someone just #included your header twice.

  14. #14
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Originally posted by darksaidin
    To me it always seemed like nothing more than a workaround for a compiler misconception. However, I admit that my opinion may be a bit biased since I never had to use headers. I think they are a pain.


    I got a question, though: In your example code, clsTree.cpp includes main.h . How does main.h know where it's implementations are? Does the compiler search for a file with the same name as main.h but a .cpp extension or how does it work? (I'm not questioning your code, I know it works, I just don't understand how.)
    The compiler does nothing of the sort. The compiler goes through each .cpp file. When it finds an #include, it just does the equivalent of copying/pasting the entire .h file into that location in the .cpp file. It then compiles the .CPP file, and produces an .obj file. When some piece of code calls a function that isn't defined in that particular .cpp file, the compiler simply "makes a note of it" and moves on.

    The linker happens next. It takes all the .obj files, and all the libraries, and tries to make all the function calls work. E.g. say main.cpp tried to call a method called "bool MyClass:Func1(int)", but that function wasn't in main.cpp. The compiler made a note of this, and it's the linker's job to search for the compiled version of that function (in any of the .obj or library files). If it finds it, it adjusts the compiled code from main.obj so that it jumps to the right address in memory. The linker creates the final .exe if it could find all the functions; otherwise, it gives an "unresolved external" error and terminates.

  15. #15
    Grammar Police HybridM's Avatar
    Join Date
    Jan 2003
    Posts
    355
    You should be on the ISO commitee Cat. You seem to know everything!
    Thor's self help tip:
    Maybe a neighbor is tossing leaf clippings on your lawn, looking at your woman, or harboring desires regarding your longboat. You enslave his children, set his house on fire. He shall not bother you again.

    OS: Windows XP
    Compiler: MSVC

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reading Process Memory
    By polydegmon in forum C# Programming
    Replies: 0
    Last Post: 05-26-2009, 07:18 AM
  2. OOP Question DB Access Wrapper Classes
    By digioz in forum C# Programming
    Replies: 2
    Last Post: 09-07-2008, 04:30 PM
  3. Linking problems in Visual Studio
    By h3ro in forum C++ Programming
    Replies: 5
    Last Post: 03-04-2008, 02:39 PM
  4. Stuck with Structs...
    By DanFraser in forum C# Programming
    Replies: 8
    Last Post: 05-03-2007, 09:55 AM
  5. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM