dll显示调用和隐式调用
生成dll:(后面调用需要此步骤中的 .h, .lib 和 .dll)
1 //CreatDLL.h 2 #pragma once//避免重复编译 3 4 #ifdef CREATDLL_EXPORTS//这个宏只要你选了项目配置类型为.dll,在预处理器里会自动包含. 5 #define DLL_API _declspec(dllexport) 6 #else 7 #define DLL_API _declspec(dllimport) //当编写文件调用时,没有该宏。因此只要不是生成dll的文件全都符合这点。这里是暗的,显然条件不成立。 8 #endif 9 10 #include <string> 11 12 namespace zsdll 13 { 14 extern "C" DLL_API void ThresholdImg(std::string SrcPath, std::string ResPath, double thresh); 15 extern "C" DLL_API void InsertSort(int *data_array, int size_array); 16 } 17 // CreatDLL.cpp : 定义 DLL 应用程序的导出函数。 18 19 #include "stdafx.h" 20 //下面都是自带的 21 #include <iostream> 22 #include <opencv2\opencv.hpp> 23 //包含同名的头文件 24 #include "CreatDLL.h" 25 26 void zsdll::ThresholdImg(std::string SrcPath, std::string ResPath, double thresh) 27 { 28 cv::Mat srcImg = cv::imread(SrcPath, 0); 29 cv::Mat resImg; 30 srcImg.copyTo(resImg); //深复制 31 cv::threshold(srcImg, resImg, thresh, 255, CV_THRESH_BINARY); 32 cv::imwrite(ResPath, resImg); 33 } 34 35 void zsdll::InsertSort(int *data_array, int size_array) 36 { 37 int *res_array = new int[size_array + 1]{ 0 }; 38 for (int i = 1; i < size_array + 1; i++) 39 { 40 res_array[i] = data_array[i - 1]; 41 } 42 43 //插入排序 44 int location{ 0 }; 45 for (int i = 2; i < size_array + 1; i++) 46 { 47 res_array[0] = res_array[i]; 48 49 for (int j = i - 1; j >= 0; j--) //遍历前面有序数据 50 { 51 location = j; 52 if (res_array[j] <= res_array[0]) 53 break; 54 res_array[j + 1] = res_array[j]; 55 } 56 57 res_array[location + 1] = res_array[0]; 58 } 59 60 std::cout << "排序结果: "; 61 for (int i = 1; i < size_array + 1; i++) 62 { 63 std::cout << res_array[i] << "\t"; 64 } 65 std::cout << std::endl; 66 67 delete[] res_array; 68 }
显示调用 :
1 //CreatDLL.h 2 #pragma once//避免重复编译 3 4 #ifdef CREATDLL_EXPORTS//这个宏只要选了创建dll类型项目,预处理器会自动宏包含, 5 #define DLL_API _declspec(dllexport) 6 #else 7 #define DLL_API _declspec(dllimport) 8 //当编写文件调用时,没有该宏,只要不是生成dll的文件全都符合这点。这里是暗的,显然条件不成立。 9 #endif 10 11 #include <string> 12 13 namespace zsdll 14 { 15 extern "C" DLL_API void ThresholdImg(std::string SrcPath, std::string ResPath, double thresh); 16 extern "C" DLL_API void InsertSort(int *data_array, int size_array); 17 //这里的extern "C",如果后面是C写的库,就用类C的方式链接;如果是C++依然是C++的方式链接。通用的! 18 } 19 // test_dll.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 20 //显示调用,和平常一样,调函数没有任何变化。 21 22 #include "pch.h"//这里可选,如果VS设置了使用预编译头,就必须包含设定的预编译头文件 23 //所谓预编译头,就是将一些常用的头文件包含进来,然后将这句直接包含进pch.cpp,这个文件可以直接设置创建预编译头文件 24 //即设置将这个预编译好的文件给整个项目使用。当第一次编译后,再编译就很快了。不会再每次先拷贝头文件等,直接调用生成的预编译文件。 25 26 #include <iostream> 27 #include <CreatDLL.h> // 1.光inlcude还不行,还需要将生成dll的头文件.h的所在目录添加到本项目的包含目录。 28 #pragma comment (lib,"CreatDLL.lib") // 2.这句话做了包含.lib的所在库目录; 29 //3.还需要将.lib添加到附加依赖项。 30 //4.将.dll拷到本项目工程目录(生成的exe文件附近,项目右键-在文件资源管理器打开) 31 32 33 void main() 34 { 35 /*图像二值化*/ 36 std::string InputPath = "src.png"; 37 std::string OutPath = "res.jpg"; 38 zsdll::ThresholdImg(InputPath, OutPath, 100); 39 std::cout << "图像二值化完成" << std::endl; 40 /*插入排序*/ 41 int *data = new int[10]{ 5,3,2,7,8,1,0,4,6,9 }; 42 std::cout << "原始数据:"; 43 for (int i = 0; i < 10; i++) 44 { 45 std::cout << data[i] << "\t"; 46 } 47 std::cout << std::endl; 48 zsdll::InsertSort(data, 10); 49 getchar(); 50 delete[] data; 51 }
隐式调用:
1 #include <Windows.h> //这俩是windows API的头文件,必须包含才能实现隐式调用 2 #include <tchar.h> 3 4 #include <stdio.h> //system("pause"),getchar() 5 #include <string> 6 7 #include <highgui.hpp> //imshow(),imread() 8 using namespace cv; 9 10 void main() 11 { 12 typedef void(*FunDLL)(std::string Input, std::string Out, double T); //声明一个函数指针 13 14 std::string InputPath = "src.png"; 15 std::string OutPath = "res.jpg";//输出文件命名为res 16 17 HMODULE hdll = LoadLibrary(_T("CreatDLL.dll"));//装载函数 18 if (hdll != NULL) 19 { 20 FunDLL ThresholdImg = (FunDLL)GetProcAddress(hdll, "ThresholdImg");//找到函数地址赋给函数指针类型ThresholdImg 21 if (ThresholdImg != NULL) 22 { 23 ThresholdImg(InputPath, OutPath, 100);//直接调用指针即可,本身函数就是一个对象,可以 24 25 } 26 } 27 Mat img = imread("res.jpg",1 ); 28 imshow("灰度图", img); 29 waitKey(30);//没有头文件依赖,可以正常显示图片。只用pause或者是getchar()都会因为线程阻塞无法正常显示图片。 30 system("pause"); //此时再加上这句,就会在图片显示出来后停住,操作后会继续经历30ms的waitKey然后结束。 31 32 FreeLibrary(hdll); 33 } 34