环境:visual studio 2015
需要打包的程序可以包含第三方的静态库 (.lib)文件,也就是说你可以使用第三方的库函数开发你的功能,然后打包。
一、设计功能模块的入口函数
功能模块的入口函数是指你开发的程序的对外的接口,也就是说生成动态库后,其他程序通过这个接口函数来使用你开发的功能。
1. 入口函数在声明时要加上“__declspec(dllexport) ”,表明这是一个入口函数。
例如 __declspec(dllexport) int function (int a, int b);
2. 如果你的动态库要在C#中托管调用,声明时要加上“extern "C" __declspec(dllexport)”;在C++中调用就不需要了。
例如 extern "C" __declspec(dllexport) int function (int a, int b);
3. 入口函数的实现,正常就可以。一般声明在.h文件中,实现在.cpp文件中。当然也可以把声明和实现写在一起。
4. 入口函数的返回值和参数类型要设计好,最好使用基础类型。(方便其他程序调用时,参数的匹配)
如果要在C#中托管,就一定要使用C/C++的基础类型。
二、生成动态库
1. 在编写程序的过程中,会有main.cpp文件,在main函数中调用入口函数,调试程序。
2. 但是生成动态库时,需要将整个main.cpp都注释,因为编译生成的库不需要main函数入口,只是要在其他程序中调用入口函数,实现功能。
3. 在visual studio中,右键工程,选择“属性”,在“属性页”中,选择“配置属性”中的“常规”,然后在右界面中的“项目默认值”中,重新选择“配置类型”,选择“动态库(dll)”选项。
4. 因为整个main.cpp都被注释了,所以程序没有入口函数,这时候直接生成,会因为没有主函数(main)而报错。所以仍然在在“属性页”中,选择“配置属性”中的“链接器”下的“系统”选项,然后在右界面中重新选择“子系统”为“窗口 (/SUBSYSTEM:WINDOWS)”,这样生成就不会报错了。
5. 在visual studio中选择“生成”,然后“生成解决方案”,要注意选择相应的版本,Debug或者Release版本。最后就可以在工程目录下的Debug或者Release目录下找到对应的 .lib 和 .dll 文件,名字与工程名字相同。
6. 如果在你的工程中使用了第三方库函数,就需要注意一下。
如果使用的是第三方的.lib 静态库,就不用管了,你编译生成的dll会包含该文件;
如果使用了其他第三方的动态库dll文件,那么在调用你自己编译的动态库时,还需要这些第三方的动态库。
7. 要使用你编译的动态库,一共要用到三种文件
头文件,也就是 .h 后缀的文件,包括你工程中自己写的所有.h文件,和第三方库的所有.h 文件,可以放在一个文件夹中,例如“include”,自己可以命名。
静态库文件,也就是 .lib 文件,就是你在步骤5中生成的那个lib文件,只有一个,可以放在一个文件夹中例如“lib”, 也可以放在你将要使用这个库的工程的目录下。
动态库文件,也就是 .dll 文件,就是你在步骤5中生成的那个dll文件,和其他你用到的第三方的dll文件,这些dll文件需要放在你将要使用这个库的工程的目录下。
三、使用自己编译的动态库
1. 新建工程项目,添加main.cpp项。
拷贝步骤二第7项中的 “include”目录、lib目录或者lib文件(没有目录)、所有动态库dll文件到新建的工程目录下,也就是和.vcxproj文件同一目录下,不是解决方案目录。
在新建工程项目的“属性页”中选择“配置属性”中的“VC++目录”,在右界面中填写“包含目录”,输入 include (和步骤二第7项中头文件目录的目录名相同就可以,因为已经拷贝到工程目录下,所以使用相对路径就可以);填写“库目录”,输入 lib(和步骤二第7项中静态库目录的目录名相同就可以,因为已经拷贝到工程目录下,所以使用相对路径就可以),如果没有静态库目录,也可以不写。
在新建工程项目的“属性页”中选择“配置属性”中的“链接器”,选择“输入”,在右界面中的“附加依赖项”中填写静态库名称,例如 xxx.lib (步骤二第7项中的lib文件名)(编译器会在你的“库目录”(如上图所示)中查找该文件并加载,如果没有库目录,会在工程目录下查找该文件并加载)
动态库拷贝到新建工程目录下就可以了,不用配置,编译器会自动找到。
2. 在main.cpp中包含你的入口函数所在的头文件,因为已经设置了“包含目录”,所以可以直接找到该头文件。
然后在main函数中调用该入口函数,要注意函数的参数要匹配。
就可以使用该函数了。
3. 编译自己的动态库,可以作为一个功能模块,方便别人调用。
还可以打包一些第三方的库函数,在新的工程中直接使用编译好的自己的库函数,不用再去为新建工程配置第三方库了。