title: C++ calling a C++ library function but the wrong function is executed
body: <p>I am calling a library class's functions from my app and a different function in the same class is being executed. This is a very large program with the android c# calling c++ functions. That part is working fine. The c++ code is calling into a dynamic (*.so) library but the wrong function is being executed.
  Working in VS2019, Clang 5.0 toolset for both the library code and the app's code. The library source code is from a third party but ported and compiled by me. The same code works fine in windows.
  The following is a condensation of the code in question.</p>
  <p>Include file contents shared by library and app code:</p>
  <p><em>assume the items pointed to (ie FileHeader etc ) are declared in an include file.</em></p>
  <pre><code>namespace nsLibraryNameSpc
  {
      class Iitems
      {
      public:
          virtual ~Iitems(void) {};
          virtual  int GetAnItem( int instance, unsigned itemID, char *fieldName ) = 0;
      };  
      class Itable
      {
      public:
          virtual ~Itable(void) {};
          virtual int GetBaseInfo( BaseInfo *pBI ) = 0;
          virtual int GetTablePtr( MainTableContents *pMTC ) = 0;
      };  
      class Imethods
      {
      public:
          virtual ~Imethods(void) {};
          virtual int StartMethod( unsigned methodNumber ) = 0;
          virtual int CancelMethod( unsigned methodNumber ) = 0;
      };  
      class Imyclass : public Iitems, public Itable, Imethods
      {
          public:
          Imyclass( void ) {};
          virtual ~Imyclass(void) {};
          
          virtual void GetFileHeader( FileHeader** pFh ) = 0;
          virtual  int AddFileHeader( const char* fileNm, const FileHeader * pFh ) = 0;
          virtual void *testCall02( void *p1, void *p2 ) = 0;
          virtual void *testCall01( void ) = 0;
      };
  }
  </code></pre>
  <p>The Library source code:</p>
  <p><em>assume the methods in classes Iitems, Itable and Imethods exist in the library.</em></p>
  <p><em>assume LOG(char *fmt,...) will log the string to a file.</em></p>
  <p>MyClass.cpp</p>
  <pre><code>class MyClass : public Imyclass
  {
  private:
      FileHeader *pHeader;
      unsigned activeMethod;
      
  public:
          MyClass( int instance )
          {
              pHeader = 0;
              activeMethod = 0;
          }       
          virtual ~MyClass() 
          {
              if (pHeader != 0)
                  delete pHeader;
          }       
          virtual void GetFileHeader( FileHeader** pFh )
          {
              LOG(&quot;Inside GetFileHeader\n&quot;);
              if (pFh != 0)
                  *pFh = pHeader;
              return;
          }       
          virtual  int AddFileHeader( const char* fileNm, const FileHeader * pFh )
          {       
              LOG(&quot;Inside AddFileHeader\n&quot;);
              //if the file exists then load the file header else return -1;
              LOG(&quot;AddFileHeader calling testCall01\n&quot;);
              testCall01();
              LOG(&quot;Exiting AddFileHeader\n&quot;);
              return 0;       
          }       
          virtual void *testCall01( void ) 
          {
              LOG(&quot;Inside testCall01\n&quot;);
              return 0;
          }       
          virtual void *testCall02( void *p1, void *p2 )
          {
              LOG(&quot;Inside testCall02\n&quot;);
              return 0;
          }       
          int GetBaseInfo( BaseInfo *pBI )
          {
              // some work
              return 0;
          }
          int GetTablePtr( MainTableContents *pMTC )
          {
              // some work
              return 0;
          }               
          int StartMethod( unsigned methodNumber )
          {
              // some work
              return 0;
          }
          int CancelMethod( unsigned methodNumber )
          {
              // some work
              return 0;
          }       
          int GetAnItem( int instance, unsigned itemID, char *fieldName )
          {
              // some work
              return 0;
          }
  }
  
  static int instCntr = 0;
  
  Imyclass *makeMyClass(void)
  {
      Imyclass * pRet = (Imyclass *) new MyClass(++instClass);
      return pRet;
  }
  </code></pre>
  <p>Android app's C++ code:</p>
  <pre><code>int testLibraryCalls(void)
  {
      Imyclass *pclass = makeMyClass();
      
      LOG(&quot;In testLibraryCalls\n&quot;);
      pclass-&gt;testCall02( (void*)0, (void*)0 );
      LOG(&quot;testCall02 finished\n&quot;);
      pclass-&gt;testCall01();
      LOG(&quot;testCall01 finished\n&quot;);
      pclass-&gt;GetFileHeader(0);
      LOG(&quot;GetFileHeader finished\n&quot;);
      AddFileHeader( (void*)0, (void*)0 );
      LOG(&quot;AddFileHeader finished\n&quot;);
  }
  </code></pre>
  <p>The log file shows:</p>
  <pre><code>In testLibraryCalls
  Inside AddFileHeader
  AddFileHeader calling testCall01
  Inside testCall01
  Exiting AddFileHeader
  testCall02 finished
  Inside testCall02
  testCall01 finished
  GetFileHeader finished
  Inside GetFileHeader
  AddFileHeader finished
  </code></pre>
  <p>So calling testCall02 is executing AddFileHeader,</p>
  <p>AddFileHeader is calling testCall01 (in the same class from the library code) correctly.</p>
  <p>Calling testCall01 from the app executes testCall02 in the library.</p>
  <p>Calling GetFileHeader from the app either doesn't execute or calls something without a LOG statement.</p>
  <p>Calling AddFileHeader executes GetFileHeader in the library.</p>
  <p>I have verified there is only one .so file on this pc with the offending functions listed in the nm output.</p>
  <p>To me, this looks like a library loader failure but I can't believe that. Any ideas about what's wrong or how to determine the root cause would be very useful.</p>
  <p>===============================================================</p>
  <p>Update: I made this top level dynamic library into a static library (*.a) and linked it into the main app. No change. Calls still went to the same wrong functions. So runtime linking is not part of the problem.</p>