Thread: Sharing an object between separate modules

  1. #1
    Registered User sonnichs's Avatar
    Join Date
    Jul 2011
    Posts
    30

    Sharing an object between separate modules

    I have compiled (with g++) and run the code "combined.cpp". It consists of the class LIBS, main and funct_correlation. A LIBS object is created as "L". Then main invokes L.getHABlib. funct_correlation then does the same.

    Now I want to separate the code into the 2 pieces shown.(separate1.cpp,separate2.cpp) This does not compile-the function "correlation" cannot "see" the "L" object. Functionally I would think this code is the same as the above but I clearly am missing something to tie them together (the gnu linker does not).

    Any help appreciated
    Fritz
    Attached Files Attached Files

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    You need a .h file that you include in both files, containing the following.

    Call it separate.h
    Code:
    #ifdef SEPARATE_H_INCLUDED
    #define SEPARATE_H_INCLUDED
    
    //////////////////////////////////////////////////////////////////////////
    class LIBS
    {
    private:
       char  HABlib[100];
    public:
        void setLIBS(int argc, char  *argv[])
        {
            strcpy(HABlib,"test");
        }
        char* getHABlib(void)   {return HABlib;} //return the ADDRESS of HABlib
    };
    
    //////////////////////////////////////////////////////////////////////////
    extern LIBS L;
    //////////////////////////////////////////////////////////////////////////
    #endif
    Then the two sources are
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/time.h>
    #include <time.h>
    #include <errno.h>
    #include <iostream>
    
    #include "separate.h"   // the file created above
    
    using namespace std;
    void funct_correlation(void);
    
    //////////////////////////////////////////////////////////////////////////
    
    // Create an instance of your object
    LIBS L;
    
    //////////////////////////////////////////////////////////////////////////
    int main( int argc, char *argv[] ) 
    {
       L.setLIBS(argc,argv);
       printf("HAB=%s\n", L.getHABlib()  ); //print string at location of address
       funct_correlation();
    
       return 0;
    } //end main
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/time.h>
    #include <time.h>
    #include <errno.h>
    #include <iostream>
    
    #include "separate.h"   // the file created above
    
    using namespace std;
    
    //////////////////////////////////////////////////////////////////////////
    void funct_correlation(void)
    {
         char HL[100];
         strcpy( HL, L.getHABlib() );
         printf("HAB from funct=%s\n", HL  ); //print string at location of address
         
         return;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    Each .cpp file (along with it's included text) forms a "compilation unit" that must be able to be compiled into an object file separately from the other .cpp files. As it stands, separate2.cpp has no knowledge of LIBS or L. Usually you would put class LIBS in a .h file and include it in separate1.cpp and separate2.cpp so they each know about that class.

    As for L, if you really want it global like you have it, then you need to let separate2.cpp know about it by adding the following at global scope in separate2.cpp:
    Code:
    extern LIBS L;  // indicate the existence of L without defining it here
    Alternatively you could define the object locally in main and pass it to the other function:
    Code:
    // libs.h ////////////////////////////////////////////////////////
     
    #ifndef LIBS_H
    #define LIBS_H
     
    #include <cstring>
     
    class LIBS
    {
    private:
        char  HABlib[100];
    public:
        void setLIBS( int argc, char  *argv[] )
        {
            strcpy(HABlib,"test");
        }
        char* getHABlib(void) { return HABlib; }
    };
     
    #endif
     
    // separate1.cpp /////////////////////////////////////////////////
     
    #include <iostream>
    #include "libs.h"
    void funct_correlation( LIBS &libs );
    using namespace std;
     
    int main( int argc, char *argv[] ) 
    {
       LIBS L;
       L.setLIBS(argc, argv);
       cout << "HAB=" << L.getHABlib() << "\n";
       funct_correlation(L);
     
       return 0;
    }
     
    // separate2.cpp /////////////////////////////////////////////////
     
    #include <iostream>
    #include <cstring>
    #include "libs.h"
    using namespace std;
     
    void funct_correlation( LIBS &L )
    {
         char HL[100];
         strcpy( HL, L.getHABlib() );
         cout << "HAB from funct=" << HL << "\n"; 
    }
    You can compile each unit separately (the -c file says to compile only, do not link yet) :
    Code:
    g++ -Wall -W -c separate1.cpp       # this will create separate1.o
    g++ -Wall -W -c separate2.cpp       # this will create separate2.o
    g++ separate1.o sepatate2.o -o separate   # this links the .o files
     
    # Or you could compile and link everything at once:
    g++ -Wall -W separate1.cpp separate2.cpp -o separate
    BTW, we don't generally mix C-style I/O and C++-style I/O, so if you're including iostream and using cout, etc., then there's no reason to include stdio.h.
    And <stdio.h> is usually spelled <cstdio> in C++; and <string.h> is <cstring>).
    We also don't put (void) for an empty parameter list, but instead just write ().
    A little inaccuracy saves tons of explanation. - H.H. Munro

  4. #4
    Registered User sonnichs's Avatar
    Join Date
    Jul 2011
    Posts
    30
    Ok and thanks for this useful input. I guess I was expecting too much of the linker.
    I added the modifications using "extern" however I preferred to move this extern to the called module. This way my class in the .h file remains untouched and I can put the external logic for each called subroutine as I use it. Works fine.
    The added comment about passing the &L as a variable makes sense. However I am never sure exactly which procedure is preferred by C++.
    Thanks for the comments on the use of void and cout. I don't use C++ enough and can't always keep track of all these nuances along with the other plethora of languages these days!

    cheers
    Fritz

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. modules help
    By Krista Koeplin in forum C++ Programming
    Replies: 5
    Last Post: 02-20-2016, 03:00 PM
  2. Modules
    By qwes3r in forum C Programming
    Replies: 9
    Last Post: 03-27-2015, 09:51 PM
  3. Help with modules
    By Jacob Boyd in forum C++ Programming
    Replies: 3
    Last Post: 10-23-2012, 10:08 AM
  4. Replies: 3
    Last Post: 11-22-2011, 04:06 AM
  5. Modules
    By Hakim in forum C++ Programming
    Replies: 2
    Last Post: 04-22-2006, 04:53 PM

Tags for this Thread