编译链接库
❶ windows下qt怎么编译静态链接库
一般分为动态库和静态库,方法分别如下:
一.
静态库的生成
1.
测试目录:
lib
2.
源码文件名:
mywindow.h,
mywindow.cpp
3.
编写项目文件:
mywindow.pro
注意两点:
TEMPLATE
=
lib
CONFIG
+=
staticlib
4.
生成Makefile:
qmake
mywindow.pro
❷ 如何用gcc编译生成动态链接库*.so文件
生成动态链接库的命令行为:
gcc -fPIC -shared -o libstr.so
当将main.c和动态链接库进行连接生成可执行文件 的命令如下:
gcc main.c -L./ -lstr -o main或者gcc -o main main.c -L./ -lstr
测试是否动态链接,如果列出libstr.so, 那么应该是连接正常了ldd main注:1)-L.:表示连接的库在当前的目录中。
❸ 编译时为什么要指定链接库
因为有些运行时代码,是预先存在“链接库”里的。没有这些库,程序无法运行。所以编译时需要指定。
“链接库”分动态和静态两种。静态的库,编译时就把相应的代码“嵌入”可执行文件中。这种可执行文件可以单独运行,基本不需要“运行时间库”支持。
而对于动态的库,编译时只获取必要的接口信息,而在运行时根据接口信息,找到对应的动态链接库,并装入内存。这种可执行文件的大小会小一些。但是需要“运行时间库”才能正常运行。
有问题继续交流,谢谢。

❹ 有个 c 文件,如何才能将其编译成动态链接库
有二个文件,一个 test.h, 一个 test.c
//test.h
#pragmaonce
#ifdef__cplusplus
extern"C"{
#endif
intadd(inta,intb);
#ifdef__cplusplus
}
#endif
//test.c
#include"test.h"
intadd(inta,intb)
{
returna+b;
}
编译,生成动态链接库:
#gcc-g3-Wall-fPIC-shared-olibtest.sotest.c
#ls-l
-rwxr-xr-x1rootroot14618Jul2413:44libtest.so
-rw-r--r--1rootroot63Jul2413:43test.c
-rw-r--r--1rootroot106Jul2413:43test.h
#nmlibtest.so
00000000002006e8a_DYNAMIC
0000000000200890a_GLOBAL_OFFSET_TABLE_
w_ITM_deregisterTMCloneTable
w_ITM_registerTMCloneTable
w_Jv_RegisterClasses
00000000002006c8d__CTOR_END__
00000000002006c0d__CTOR_LIST__
00000000002006d8d__DTOR_END__
00000000002006d0d__DTOR_LIST__
00000000000006b8r__FRAME_END__
00000000002006e0d__JCR_END__
00000000002006e0d__JCR_LIST__
00000000002008b8d__TMC_END__
00000000002008b8A__bss_start
w__cxa_finalize@@GLIBC_2.2.5
0000000000000620t__do_global_ctors_aux
0000000000000550t__do_global_dtors_aux
00000000002008b0d__dso_handle
w__gmon_start__
00000000002008b8A_edata
00000000002008c8A_end
0000000000000658T_fini
0000000000000468T_init
0000000000000600Tadd
00000000000004a0tcall_gmon_start
00000000002008b8bcompleted.6557
00000000000004c0tderegister_tm_clones
00000000002008c0bdtor_idx.6559
00000000000005d0tframe_mmy
0000000000000500tregister_tm_clones
❺ 如何编译C/Fortran动态/静态链接库
首先,传统的编译,也就是静态编译是把 源文件 翻译成目标文件,这个是一次性过程,也就是你所谓的静态编译。
后来的Java和.NET等语言,首先编译成中间形式,然后运行过程中根据需要编译成本地代码(注意这个过程不是一次性的,下次运行重新编译),这个就是JIT(即时编译)技术,从即时编译发展出了动态编译技术
————————————
(传统的)编译完成后,像C/C++、Fortran、汇编等语言,可以把多个目标文件合并到一个库文件中,这个就是静态库。比如常说的库函数printf就是libc里面的函数。
如果有了启动函数(main),main里面使用了printf,就可以通过静态链接技术,从libc中提取出printf所在的文件加入到可执行文件中,如果printf还需要其它函数,就继续搜索并加入列表,直到形成一个闭包。这个就是静态链接。
可是静态链接有个明显的缺点,如果每个程序都需要printf,那么printf这个函数的代码就会同时存在在每个程序中,这样也太占地方了吧。所以发明了动态连接技术,其实有两种形式。无论哪一种,都是首先记录下需要调用printf这个函数以及所在的动态库,等到运行的时候再加载动态库,从动态库中找到真正的printf去执行。
由于,动态链接技术需要一些额外的信息,传统的静态库是不具备的,这些额外信息主要是重复加载和卸载时所需要的一些代码,因此需要动态链接库。
❻ 如何在Windows下编译sqlite3,生成动态链接库并使用
一. 编译动态链接库库文件
下面的是我的编译过程,或许对你有些帮助:
1). 打开VC新建一个“Win32 Dynamic-Link Library”工程,命名为:sqlite3
2). 在接下来的对话框中选择"An empty DLL project",点 FINISH->OK
3). 将源码中所有的 *.c *.h *.def 复制到工程文件夹下
4). 在工程的Source File中添加你下载到的SQLite源文件中所有*.c文件,
注意这里不要添加shell.c和tclsqlite.c这两个文件。
5). 将 SQLite 源文件中的 sqlite3.def 文件添加到在工程的Source File中
6). 在Header File中添加你下载到的SQLite源文件中所有*.h文件,
7). 开始编译,Build(F7)一下
也许到这里会遇到一个错误:
e:\zieckey\sqlite\sqlite3\sqlite3ext.h(22) : fatal error C1083: Cannot open include file: 'sqlite3.h': No such file or directory
经检查发现,源码中包含sqlite3.h都是以 #include <sqlite3.h> 方式包含的,
这就是说编译器在系统默认路径中搜索,这样当然搜索不到 sqlite3.h 这个头文件啦,
这时可以改为 #include "sqlite3.h" ,让编译器在工程路径中搜索,
但是如果还有其他地方也是以 #include <sqlite3.h> 方式包含的,那么改源码就显得有点麻烦,
好了,可以这样,在菜单栏依次选择:Tools->Options...->Directeries
在下面的Directeries选项中输入你的 sqlite3.h 的路径,这里也就是你的工程目录.
添加好后,在编译一下就好了,
最后在工程目录的 Debug 目录生成了下面两个重要文件:
动态链接库文件 sqlite3.dll 和引入库文件 sqlite3.lib
二. 使用动态链接库
下面来编写个程序来测试下动态链接库.
在VC下新建一个空的"Win32 Console Application" Win32控制台程序,工程命名为:TestSqliteOnWindows
再新建一个 test.cpp 的C++语言源程序,源代码如下:
// name: test.cpp
// This prog is used to test C/C++ API for sqlite3 .It is very simple,ha !
// Author : zieckey
// data : 2006/11/28
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
#define _DEBUG_
int main( void )
...{
sqlite3 *db=NULL;
char *zErrMsg = 0;
int rc;
rc = sqlite3_open("zieckey.db", &db); //打开指定的数据库文件,如果不存在将创建一个同名的数据库文件
if( rc )
...{
fprintf(stderr, "Can't open database: %s ", sqlite3_errmsg(db));
sqlite3_close(db);
return (1);
}
else printf("You have opened a sqlite3 database named zieckey.db successfully! Congratulations! Have fun ! ^-^ ");
//创建一个表,如果该表存在,则不创建,并给出提示信息,存储在 zErrMsg 中
char *sql = " CREATE TABLE SensorData(ID INTEGER PRIMARY KEY,SensorID INTEGER,SiteNum INTEGER,Time VARCHAR(12),SensorParameter REAL);" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );
#ifdef _DEBUG_
printf("zErrMsg = %s ", zErrMsg);
#endif
//插入数据
sql = "INSERT INTO "SensorData" VALUES(NULL , 1 , 1 , '200605011206', 18.9 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );
sql = "INSERT INTO "SensorData" VALUES(NULL , 23 , 45 , '200605011306', 16.4 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );
sql = "INSERT INTO "SensorData" VALUES(NULL , 34 , 45 , '200605011306', 15.4 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );
int nrow = 0, ncolumn = 0;
char **azResult; //二维数组存放结果
//查询数据
sql = "SELECT * FROM SensorData ";
sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );
int i = 0 ;
printf( "row:%d column=%d " , nrow , ncolumn );
printf( " The result of querying is : " );
for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ )
printf( "azResult[%d] = %s ", i , azResult[i] );
//删除数据
sql = "DELETE FROM SensorData WHERE SensorID = 1 ;" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );
#ifdef _DEBUG_
printf("zErrMsg = %s ", zErrMsg);
#endif
sql = "SELECT * FROM SensorData ";
sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );
printf( " row:%d column=%d " , nrow , ncolumn );
printf( " After deleting , the result of querying is : " );
for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ )
printf( "azResult[%d] = %s ", i , azResult[i] );
//释放掉 azResult 的内存空间
sqlite3_free_table( azResult );
#ifdef _DEBUG_
printf("zErrMsg = %s ", zErrMsg);
#endif
sqlite3_close(db); //关闭数据库
return 0;
}
另外,将sqlite3.h sqlite3.lib sqlite3.dll文件复制到工程目录.
最后 Project->Settings 在Link选项卡找到Object/library moles : 在最后填入sqlite3.lib 。
如果原来就有链接,请使用空格分隔。
现在可以编译了.
运行结果如下:
You have opened a sqlite3 database named zieckey.db successfully!
Congratulations! Have fun ! ^-^
zErrMsg = (null)
row:3 column=5
The result of querying is :
azResult[0] = ID
azResult[1] = SensorID
azResult[2] = SiteNum
azResult[3] = Time
azResult[4] = SensorParameter
azResult[5] = 1
azResult[6] = 1
azResult[7] = 1
azResult[8] = 200605011206
azResult[9] = 18.9
azResult[10] = 2
azResult[11] = 23
azResult[12] = 45
azResult[13] = 200605011306
azResult[14] = 16.4
azResult[15] = 3
azResult[16] = 34
azResult[17] = 45
azResult[18] = 200605011306
azResult[19] = 15.4
zErrMsg = (null)
row:2 column=5
After deleting , the result of querying is :
azResult[0] = ID
azResult[1] = SensorID
azResult[2] = SiteNum
azResult[3] = Time
azResult[4] = SensorParameter
azResult[5] = 2
azResult[6] = 23
azResult[7] = 45
azResult[8] = 200605011306
azResult[9] = 16.4
azResult[10] = 3
azResult[11] = 34
azResult[12] = 45
azResult[13] = 200605011306
azResult[14] = 15.4
zErrMsg = (null)
Press any key to continue
这个程序,我们先创建一个数据库,然后新建一个表,然后插入一些数据,
再查询看看插入的数据是否正确,然后又删除一些数据,删除后我们再查询了一下,
发现我们的删除操作也是成功的.
这个程序简单的调用 sqlite 的函数接口来实现对数据库的管理,
包括创建数据库、创建表格、插入数据、查询数据、删除数据等。
注:在上面的第五步
5). 将 SQLite 源文件中的 sqlite3.def 文件添加到在工程的Source File中
是必须的, sqlite3.def 这个文件的加入会生成 *.lib引入库文件,这个对于*.dll文件是很重要的.否则你光有*.dll文件在程序调用的时候就不是那么方便了,因为这样你只能通过动态加载dll的方式调用dll库中函数
三、如何编译sqlite3.4.2版本 (本人原创:添加于 2007年9月29日)
其实这个版本的比之前的更好编译而且很简单。
步骤如下:
1、在网站下载源文件,选择“sqlite-amalgamation-3_4_2.zip”。此文件中包含了sqlite3.h和sqlite3.c两个文件。
2、下载“sqlitedll-3_4_2.zip”,次文件中包含编译好的DLL文件和DEF文件,DEF文件用来在编译时生成lib文件。(重点)
3、打开VC新建一个“Win32 Dynamic-Link Library”工程,命名为:sqlite3
4、 在接下来的对话框中选择"An empty DLL project",点 FINISH->OK
5、将解压后的 *.c *.h *.def 复制到工程文件夹下
6、在工程的Source File中添加你下载到的SQLite源文件中sqlite3.c文件,
7、 将 SQLite 源文件中的 sqlite3.def 文件添加到在工程的Source File中
8、在Header File中添加你下载到的SQLite源文件中的sqlite3.h文件,
9、 开始编译,Build(F7)一下。
❼ ros编译提示缺少链接库怎么办
一、标准:ROS功能包中调用第三方静态库
include_directories(
include
${catkin_INCLUDE_DIRS}
)
add_executable(${PROJECT_NAME}_node src/source.cpp
include/source.h
)
target_link_libraries(${PROJECT_NAME}_node
${catkin_LIBRARIES}
${PROJECT_SOURCE_DIR}/lib/第三方库名
)
以上一般情况下都没问题,但是有些静态库没有添加pie系统保护功能,导致程序转载的地址是无效的,所以我们在链接时候也需要关闭pie功能。
注:引入PIE的原因是让程序能装载在随机的地址,通常情况下,内核都在固定的地址运行,如果能改用位置无关,那攻击者就很难借助系统中的可执行码实施攻击了。类似缓冲区溢出之类的攻击将无法实施。而且这种安全提升的代价很小
二、解决链接未开启pie功能的静态库时,编译报错
先作对比:
include_directories(
include
${catkin_INCLUDE_DIRS}
)
add_executable(${PROJECT_NAME}_node src/source.cpp
include/source.h
)
target_link_libraries(${PROJECT_NAME}_node
${catkin_LIBRARIES}
${PROJECT_SOURCE_DIR}/lib/第三方库名 -no-pie
)
与一般的链接形式对比,我们只是在链接第三方库的后面加了-no-pie,之后再到ROS的工作空间中重新编译就完成了!
❽ 如何编译 opencv动态链接库
在一个项目中需要用到OpenCV,刚开始使用了OpenCV的动态链接库,这样,在移动可执行程序时还必须将OpenCV动态支持库一起搬移,很是麻烦。所以,最终选择OpenCV静态链接库,这样程序移植运行就方便了很多。
需要编译成静态库以便于应用程序链接。
网上有的教程中写的在VC++2010下安装OpenCV2.1时用到了TBB库,而我在编译链接自己的程序后需要用到TBB.dll。本人设计的目的就是要做一个独立的界面程序,不需要携带其他第三方库。经过一段时间的努力最终找到了编译OpenCV2.1静态库的方法。
需要的工具环境及文件:
-------------------------------------------------------------------------------------------------------------
1、Windows XP
2、VC++2010(VS2010)
3、为编译OpenCV源码包(我下载的有:OpenCV2.1.0,OpenCV2.3.0及OpenCV2.4.4)
4、CMake2.8.9
说明:OpenCV各版本官方下载地址:opencv.org/
cmake-2.8.9下载地址:ishare.iask.sina.com.cn/download/explain.php?fileid=35025936
--------------------------------------------------------------------------------------------------------------
以OpenCV2.1.0编译静态库为例
CMake配置
-------------------------------------------------------------------------------------------------------------
打开CMake并设置:
Where is the rource code :OpenCV源代码所在的文件夹
Where to build the binaries:CMake配置好得到的文件放在位置(我的:E:\OpenCV2.1.0-prj)
然后点击configure,选择"Visual Studio 10"。然后确定。
等待configure完成,会出现很多红色的选项,因为主要是生成OpenCV的库,所以只需保留某些选项:
去掉BUILD_NEW_PYTHON_SUPPORT,BUILD_SHARED_LIBS, BUILD_TESTS
勾选OPENCV_BUILD_3RDPARTY_LIBS, WITH_TBB,WITH_JASPER, WITH_JPEG,
WITH_PNG, WITH_TIFF选项,
然后再点击configure,如下图:
提示TBB_INCLUDE_DIR找不到,因为我们不需要TBB库,所以忽略,再一次点击configure。
等待配置完成,最后点击generate,完成后关闭CMake。
-------------------------------------------------------------------------------------------------------------
VC++2010编译静态库
-------------------------------------------------------------------------------------------------------------
进入E:\OpenCV2.1.0-prj目录,使用VC++2010打开.sln文件,打开项目管理器
这时候会看到
解决方案中有很多小项目存在。
注:这时我们右键任意点击一个子项目(如cv),选择属性,可以在配置属性下的常规项目中看到,配置类型为
静态库(lib)。
按住ctrl键,选中除过ALL_BUILD, INSTALL, ZERO_CHECK,
uninstall四个项目的其他所有项目,在菜单中选择项目->属性,打开配置属性->c/c++->代码生成选项,在右侧窗口中的运行时库中选择多线程调试(/MTd),然后确认。
说明:这里有四个选项(/MT, /MTd, /MD,
/MDd),前两个一组,为静态链接运行时库,运行时不需要运行时库的支持,代码直接插入到程序中去;后两个一组,为动态链接运行时库,运行时需要msvcr90.dll或msvcp90.dll支持。
我们先编译Debug版的OpenCV静态库,在解决方案"opencv"(22个项目)上单击右键,选择重新生成解决方案,此时便开始编译OpenCV库了,等编译结束会提示完成16个,失败4个:
这四个项目生成的是exe程序,不需要管他们。到这步我们已经生成了Debug版本的静态库!
然后我们用相同的方式生成Release版的库,在之前的基础上只需要将选项选择多线程/MT,再进行编译。编译时警告很多,直接忽略!
注意:/MT即是Release版本,/MTD即是Debug版本。
最终我们需要的静态库就存在:E:\OpenCV2.1.0-prj/lib 和 E:\OpenCV2.1.0-prj/3rdparty/lib
两个目录,我们编译好的库就在这两个文件夹下。分别
将E:\OpenCV2.1.0-prj/3rdparty/lib中Debug
下面的所有文件Copy到E:\OpenCV2.1.0-prj/lib中的Debug 文件中。
将E:\OpenCV2.1.0-prj/3rdparty/lib中Release下面的所有文件Copy到E:\OpenCV2.1.0-prj/lib中的Release文件中。
❾ linux 编译怎么连接动态库
Linux的动态库文件是以lib字样开头的.so文件,编译链接动态库有两个要点:一个是需要用-L选项指定动态库的搜索路径,这个搜索路径是需要连接的so文件的大致路径,比如/usr/openssl/lib;另外还需要用-l(这个是小写的L)选项指定动态库的名字,比如下面这条编译命令:
gcc -o hello hello.c -L/usr/openssl/lib -lcrypto
❿ 如何编译C/Fortran动态/静态链接库
首先,传统的编译,也就是
静态编译
是把
源文件
翻译成目标文件,这个是一次性过程,也就是你所谓的静态编译。
后来的Java和.NET等语言,首先编译成中间形式,然后运行过程中根据需要编译成本地代码(注意这个过程不是一次性的,下次运行重新编译),这个就是JIT(即时编译)技术,从即时编译发展出了动态编译技术
————————————
(传统的)编译完成后,像C/C++、Fortran、汇编等语言,可以把多个目标文件合并到一个
库文件
中,这个就是静态库。比如常说的
库函数
printf就是libc里面的函数。
如果有了启动函数(main),main里面使用了printf,就可以通过
静态链接
技术,从libc中提取出printf所在的文件加入到可执行文件中,如果printf还需要其它函数,就继续搜索并加入列表,直到形成一个
闭包
。这个就是静态链接。
可是静态链接有个明显的缺点,如果每个程序都需要printf,那么printf这个函数的代码就会同时存在在每个程序中,这样也太占地方了吧。所以发明了动态连接技术,其实有两种形式。无论哪一种,都是首先记录下需要调用printf这个函数以及所在的
动态库
,等到运行的时候再加载动态库,从动态库中找到真正的printf去执行。
由于,
动态链接
技术需要一些额外的信息,传统的静态库是不具备的,这些额外信息主要是重复加载和卸载时所需要的一些代码,因此需要
动态链接库
。
