MinGW编译器的全称是 Minimalist GNU for Windows。它提供了一个开发环境,使开发者可以在Windows上编写、编译和调试使用C、C++、Fortran等语言编写的程序,MinGW的核心是GCC编译器。
SMVC编译器的全称是 Simple Model-View-Controller,使用PHP框架,是Visual Studio软件中常用的编译方法。
一般使用minGW编译出的动态库和静态库格式分别为.dll和.dll.a;使用 SMVC 编译的动态库和静态库格式分别为.dll和.lib。两种格式的库文件不通用。
一、MinGW 编译
在CMakeLists文件中包含工程中用到的库文件,使用add_library命令编译出动态库,配置好该文件,其中Opencv的动态库地址已加入系统的环境变量中。
cmake_minimum_required(VERSION 3.5)
set(PROJECT_NAME PointLaserCalibration)
project(${PROJECT_NAME})
set(CMAKE_CXX_STANDARD 11)
set(OpenCV_DIR "D:/openCV/OpenCV-MinGW-Build-4.5.2/x64/mingw/lib")
find_package(OpenCV REQUIRED)
include_directories(
include
${OpenCV_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}
)
set(SOURCES
src/CPointLaserCalibration.cpp
)
add_library(${PROJECT_NAME} SHARED ${SOURCES})
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
target_compile_definitions(${PROJECT_NAME} PRIVATE MYLIBRARY_EXPORTS)
一般情况下,会使用下方的编译命令,这种方法编译出来的是.dll格式的动态库和.dll.a格式的静态库。
cmake -G "MinGW Makefiles" ..
cmake ..
cmake --build .
如果想要编译出.lib格式的静态库,需要在生成Makefile时将GNUtoMS打开,命令如下:
cmake -G “MinGW Makefiles” -DCMAKE_GNUtoMS:BOOL=ON ..
cmake ..
cmake --build .
至此,使用minGW编译出.dll和.lib。
注意:用此法编译出来的.dll和.lib,本人并没有在VS项目中成功使用,也就是说在本文下一部分中替换掉SMVC 编译出的.dll和.lib后,程序不能启动。问题待排查。
使用库文件
测试项目结构如下:
CMakeLists文件如下:
cmake_minimum_required(VERSION 3.5)
set(PROJECT_NAME TestPointLaserCalibration)
project(${PROJECT_NAME})
set(CMAKE_CXX_STANDARD 11)
set(OpenCV_DIR "D:/openCV/OpenCV-MinGW-Build-4.5.2/x64/mingw/lib")
find_package(OpenCV REQUIRED)
# 指定头文件目录
include_directories(${CMAKE_SOURCE_DIR}/dll)
# 指定库文件目录
link_directories(${CMAKE_SOURCE_DIR}/dll)
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} PointLaserCalibration)
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
头文件 CPointLaserCalibration.h 如下:
#include<opencv2/opencv.hpp>
#define Smpclass_API ;
#ifdef Smpclass_API
#define Smpclass_API __declspec(dllexport)
#else
#define Smpclass_API __declspec(dllimport)
#endif
class Smpclass_API CPointLaserCalibration {
public:
void calculateDtofPitch(const cv::Point3f& laser_point, float& pitch_angular);
int getTestNum();
};
测试程序如下:实测输出无误
#include <iostream>
#include "CPointLaserCalibration.h"
int main()
{
std::cout << "Starting the program..." << std::endl;
CPointLaserCalibration laserCalibration;
float pitch_angular = 0.0;
cv::Point3f laser_point(0.0, 0.0, 0.0);
laserCalibration.calculateDtofPitch(laser_point, pitch_angular);
int test_num = 1;
test_num = laserCalibration.getTestNum();
std::cout << "Pitch Angular: " << pitch_angular << std::endl;
std::cout << "test_num: " << test_num << std::endl;
return 0;
二、SMVC 编译
在VS中新建一个动态链接库(DLL)的项目。
把自己需要编译出动态库的代码导入进来,项目自动生成的pch.h和pch.cpp文件不用管,但也不能删除。
自己的头文件:
#include<iostream>
#include<opencv2/opencv.hpp>
#include<fstream>
#include<string>
#define Smpclass_API
#ifdef Smpclass_API
#define Smpclass_API __declspec(dllexport)
#else
#define Smpclass_API __declspec(dllimport)
#endif
class Smpclass_API CPointLaserCalibration
{
public:
CPointLaserCalibration();
struct TCameraParameter
{
cv::Mat camera_matrix; // 内参矩阵
cv::Mat rotat_matrix; // 旋转矩阵
cv::Mat trans_vector; // 平移向量
};
void printTest();
void getCameraParameter();
void initLog();
private:
cv::Rect m_out_rect; // 四个黑色矩形的外接矩形
cv::Point m_out_rect_center_pixel; // 四个黑色矩形的外接矩形中心的像素坐标
TCameraParameter m_camera_para_100;
};
自己的cpp文件:
注意 #include “pch.h” 要放在最上面
#include "pch.h"
#include "CPointLaserCalibration.h"
CPointLaserCalibration::CPointLaserCalibration()
{
getCameraParameter();
initLog();
printTest();
}
void CPointLaserCalibration::printTest()
{
std::cout << "test success!!!" << std::endl;
}
// 截断
在项目的属性设置中,把项目本身的头文件和所用库的头文件都写入“包含目录”;把项目用到的所有静态库位置都写入“库目录”
把项目用到的静态库都加入到下图中的位置
右击项目,选择“生成”即可编译出.dll动态库和.lib静态库
使用库文件
在VS中新建一个空项目,同上面的操作一样,把头文件目录和库目录都包含起来,把自己的库文件和其他的库文件都链接到附加依赖项。按照原头文件中的函数声明方法调用自己的库文件,把所有用到的dll动态库文件和编译生成的exe文件单独放在一个文件夹中即可运行。
lib静态库文件只是在编译时用到,需要把函数声明编译到exe文件中,在运行exe文件时,只用到dll动态库文件。也就是说,在后续项目维护时需要改动库文件时,只需要替换最新的dll动态库文件即可。