Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
424 views
in Technique[技术] by (71.8m points)

c - undefined reference to function declared in *.h file

I am a unskilled programmer and new to linux, I run into a problem when complining. I have two files 'ex_addinst.c' and 'lindo.h' in the same folder, I input command :

g++ -c ex_addinst.c

then, a object file ex_addinst.o is genetated with a warning:

ex_addinst.c: In function ‘int main()’:
ex_addinst.c:80: warning: deprecated conversion from string constant to ‘char*’

then I leak them with

g++ -Wall -o ex_addinst ex_addinst.o

and get the following info:

ex_addinst.o: In function `main':
ex_addinst.c:(.text+0x2b): undefined reference to `LSloadLicenseString'
ex_addinst.c:(.text+0x75): undefined reference to `LSgetVersionInfo'
ex_addinst.c:(.text+0xae): undefined reference to `LScreateEnv'
ex_addinst.c:(.text+0x10a): undefined reference to `LSgetErrorMessage'
...
...
ex_addinst.c:(.text+0x1163): undefined reference to `LSdeleteEnv'
collect2: ld returned 1 exit status

I guess that the header file 'lindo.h' is not complied into the .o file, but I have no idea what to do now. I have tried gcc, but get the same error. the version of my g++ and gcc is 4.4.5. I am using Ubuntu 10.10.

All the functions and structures have been declared in 'lindo.h'.

part of ex_addinst.c is as follows:

    #include <stdio.h>
    #include <stdlib.h>
    /* LINDO API header file */
    #include "lindo.h"
        enter code here
int CALLTYPE LSwriteMPIFile(pLSmodel pModel,
                             char     *pszFname);


/* Define a macro to declare variables for
    error checking */
#define APIERRORSETUP  
   int nErrorCode; 
   char cErrorMessage[LS_MAX_ERROR_MESSAGE_LENGTH] 
/* Define a macro to do our error checking */
#define APIERRORCHECK  
   if (nErrorCode) 
   { 
      if ( pEnv) 
      { 
         LSgetErrorMessage( pEnv, nErrorCode, 
          cErrorMessage); 
         printf("nErrorCode=%d:  %s
", nErrorCode, 
          cErrorMessage); 
      } else {
         printf( "Fatal Error
"); 
      } 
      exit(1); 
   } 

#define APIVERSION 
{
    char szVersion[255], szBuild[255];
    LSgetVersionInfo(szVersion,szBuild);
    printf("
LINDO API Version %s built on %s
",szVersion,szBuild);
}
/* main entry point */
int main()
{
   APIERRORSETUP;
   pLSenv pEnv;
   pLSmodel pModel;
   char MY_LICENSE_KEY[1024];

 /*****************************************************************
  * Step 1: Create a model in the environment.
  *****************************************************************/
   nErrorCode = LSloadLicenseString("home/li/work/tools/lindo/lindoapi/license/lndapi60.lic", MY_LICENSE_KEY);
   if ( nErrorCode != LSERR_NO_ERROR)
   {
      printf( "Failed to load license key (error %d)
",nErrorCode);
      exit( 1);
   }
......
......
......
   APIERRORCHECK;
   {
      int nStatus;
      double objval=0.0, primal[100];
      /* Get the optimization result */
      nErrorCode = LSgetInfo(pModel, LS_DINFO_GOP_OBJ, &objval);
      APIERRORCHECK;
      LSgetMIPPrimalSolution( pModel, primal) ;
      APIERRORCHECK;
      printf("

Objective = %f 
",objval);
      printf("x[0] = %f 
",primal[0]);
      printf("x[1] = %f 
",primal[1]);
      /* Get the linearity of the solved model */
      nErrorCode = LSgetInfo (pModel, LS_IINFO_GOP_STATUS, &nStatus);
      APIERRORCHECK;
      /* Report the status of solution */
      if (nStatus==LS_STATUS_OPTIMAL || nStatus==LS_STATUS_BASIC_OPTIMAL)
      printf("
Solution Status: Globally Optimal
");
      else if (nStatus==LS_STATUS_LOCAL_OPTIMAL)
      printf("
Solution Status: Locally Optimal

");
      else if (nStatus==LS_STATUS_INFEASIBLE)
      printf("
Solution Status: Infeasible

");
   }

 /* >>> Step 7 <<< Delete the LINDO environment */
   LSdeleteEnv(&pEnv);

  /* Wait until user presses the Enter key */
   printf("Press <Enter> ...");
   getchar();
}

part of 'lindo.h' is:

/*********************************************************************
 * Structure Creation and Deletion Routines (4)                      *
 *********************************************************************/

 pLSenv CALLTYPE LScreateEnv(int     *pnErrorcode,
                             char    *pszPassword);

 pLSmodel CALLTYPE LScreateModel(pLSenv pEnv,
                             int     *pnErrorcode);

 int CALLTYPE LSdeleteEnv(pLSenv *pEnv);


 int CALLTYPE LSdeleteModel(pLSmodel *pModel);


 int CALLTYPE LSloadLicenseString(char *pszFname, char *pachLicense);

 void CALLTYPE LSgetVersionInfo(char *pachVernum, char    *pachBuildDate);

Thank you!


Thank you guys answering my problem. As you suggested, I need to link the library when complining. I have gotten the executable file with:

gcc -o ex_addinst  ./ex_addinst.o -L/home/li/work/tools/lindo/lindoapi/bin/linux64 -m64 -llindo64  -lmosek64 -lconsub3 -lc -ldl -lm -lguide -lpthread -lsvml -limf -lirc

but there comes another problem when run the executable file ex_addinst: after run:

./ex_addinst

there comes:

./ex_addinst: error while loading shared libraries: liblindo64.so.6.0: cannot open shared object file: No such file or directory

The tricky thing is, liblindo64.so.6.0 is in the lib folder which contains:

libconsub3.so  libirc.so          liblindojni.so        libmosek64.so.5.0  lindo.par
libguide.so    liblindo64.so      liblindojni.so.6.0.3  libsvml.so         placeholder
libimf.so      liblindo64.so.6.0  libmosek64.so         lindoapivars.sh    runlindo

I have created symbolic links between liblindo64.so.6.0 and liblindo64.so with

ln -sf liblindo64.so.6.0 liblindo64.so

but it doesn't help.

Can anyone tell me what is wrong here?

(I am not sure I should put this question in a new post, but I think currently it is better to follow the old one)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Ok, lindo.h contains the prototypes for those functions, but where are the functions actually defined? If they're in another C file you need to compile that one too, and link both the object files together.

If the functions are part of another static library, you need to tell the linker to link that library along with your object file.

If they're defined with a shared library, you can probably get g++ to still link to it at compile time, and take care of the library loading etc. Otherwise you'll need to load the library at runtime and reference the functions from the library. This Wikipedia article on dynamic loading of shared libraries contains some example code.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...