我是一名不熟练的程序员,也不熟悉linux,我在编译时遇到了问题。我在同一文件夹中有两个文件'ex_addinst.c'和'lindo.h',我输入命令:
g++ -c ex_addinst.c
然后,对象文件ex_addinst.o被发出警告:
ex_addinst.c: In function ‘int main()’:
ex_addinst.c:80: warning: deprecated conversion from string constant to ‘char*’
然后我用
泄漏它们g++ -Wall -o ex_addinst ex_addinst.o
并获取以下信息:
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
我想头文件'lindo.h'没有编译到.o文件中,但我不知道现在要做什么。我尝试过gcc,但得到同样的错误。我的g ++和gcc的版本是4.4.5。我正在使用Ubuntu 10.10。
所有的功能和结构都在'lindo.h'中声明。
ex_addinst.c的一部分如下:
#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\n", nErrorCode, \
cErrorMessage); \
} else {\
printf( "Fatal Error\n"); \
} \
exit(1); \
} \
#define APIVERSION \
{\
char szVersion[255], szBuild[255];\
LSgetVersionInfo(szVersion,szBuild);\
printf("\nLINDO API Version %s built on %s\n",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)\n",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("\n\nObjective = %f \n",objval);
printf("x[0] = %f \n",primal[0]);
printf("x[1] = %f \n",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("\nSolution Status: Globally Optimal\n");
else if (nStatus==LS_STATUS_LOCAL_OPTIMAL)
printf("\nSolution Status: Locally Optimal\n\n");
else if (nStatus==LS_STATUS_INFEASIBLE)
printf("\nSolution Status: Infeasible\n\n");
}
/* >>> Step 7 <<< Delete the LINDO environment */
LSdeleteEnv(&pEnv);
/* Wait until user presses the Enter key */
printf("Press <Enter> ...");
getchar();
}
'lindo.h'的一部分是:
/*********************************************************************
* 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);
谢谢!
谢谢你们回答我的问题。正如你的建议,我需要在编译时链接库。我已经获得了可执行文件:
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
但运行可执行文件 ex_addinst 时出现另一个问题:运行后:
./ex_addinst
来了:
./ex_addinst: error while loading shared libraries: liblindo64.so.6.0: cannot open shared object file: No such file or directory
棘手的是, liblindo64.so.6.0 位于lib文件夹中,其中包含:
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
我在 liblindo64.so.6.0 和 liblindo64.so 之间创建了符号链接
ln -sf liblindo64.so.6.0 liblindo64.so
但它没有帮助。
谁能告诉我这里有什么问题?
(我不确定我是否应该把这个问题放在一个新帖子中,但我认为现在最好跟随旧帖子)
答案 0 :(得分:15)
好的,lindo.h
包含这些函数的原型,但实际定义的函数在哪里?如果它们在另一个C文件中,您也需要编译它,并将两个目标文件链接在一起。
如果函数是另一个静态库的一部分,则需要告诉链接器将该库与目标文件链接起来。
如果用共享库定义它们,你可能会在编译时让g ++仍然链接到它,并负责库加载等。否则你需要在运行时加载库并引用它图书馆的功能。这篇关于dynamic loading共享库的维基百科文章包含一些示例代码。
答案 1 :(得分:1)
尝试
g ++ -Wall -o ex_addinst ex_addinst。 c
而不是
g ++ -Wall -o ex_addinst ex_addinst.o
您想要编译.c文件,而不是.o文件。
答案 2 :(得分:1)
您需要告诉gcc链接包含您正在使用的LS ...函数的库或目标文件。头文件告诉编译器如何调用它们,但链接器需要知道从哪里获取编译代码。
答案 3 :(得分:0)
undefined reference to ...
不是声明问题。编译器失败,因为它找不到与那些声明的函数相关的符号(对象)
在您的情况下,您使用Limbo API,并包含头文件,但您不告诉编译器链接库:这就是它找不到符号的原因。
编辑:当你说你刚接触Linux时,我已经忘记了这个部分。要与库链接,您需要使用g ++的-L
/ -l
选项。 man g++
总是很好读,Limbo的文档也应该是。