前面写了一篇关于C++封装DLL的文章,这里是做一个补充。
一、关于如何配置halcon和opencv库不再多说,前面文章介绍的很详细。下面介绍封装新增的东西。
1.1 首先创建类function1,并编写function.h和function1.cpp代码。
function1.h代码
#pragma once
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <windows.h>
#include <thread>
#include <vector>
#include <algorithm>
#include <Halcon.h>
#include <HalconCpp.h>
using namespace std;
using namespace HalconCpp;
enum ErrorType
{
Intrusion = 0,//缺口
Protrusion,//突起
CornerMiss//缺角
};
struct mStruct
{
//输入参数
int id;
HObject Img;
int threshold_Min;
int threshold_Max;
//输出参数
double &Area;
};
class function1
{
public:
function1();
~function1();
public:
int add(int a, int b);
int subtract(int a, int b);
//Halcon算法测试
int TransferHobj_Test(mStruct &Struct1);
};
function1.cpp代码
#include "pch.h"
#include "function1.h"
function1::function1(){}
function1::~function1(){}
int function1::add(int a,int b)
{
return a + b;
}
int function1::subtract(int a, int b)
{
return a - b;
}
//传递Hobject图像测试函数
int function1::TransferHobj_Test(mStruct &Struct1)
{
try
{
HObject ho_Regions, ho_ConnectedRegions;
HObject ho_SelectedRegions;
HTuple hv_Number, hv_Area, hv_Row, hv_Column;
Threshold(Struct1.Img, &ho_Regions, Struct1.threshold_Min, Struct1.threshold_Max);
Connection(ho_Regions, &ho_ConnectedRegions);
SelectShape(ho_ConnectedRegions, &ho_SelectedRegions, "area", "and", 1.19836e+007,
2e+007);
CountObj(ho_SelectedRegions, &hv_Number);
if (0 != (hv_Number == 1))
{
AreaCenter(ho_SelectedRegions, &hv_Area, &hv_Row, &hv_Column);
Struct1.Area = hv_Area.D();
}
else
{
Struct1.Area = 0;
}
return 0;
}
catch (...)
{
return 1;
}
}
1.2 分别创建DllEntry.h和DllEntry.cpp作为上位机调用接口类,打开项目属性,找到C/C++预处理器,进入预处理器定义。在最下面加上MYDLL。然后编辑DllEntry.h和DllEntry.cpp代码。在头文件中加上下面的代码,然后再写别的代码
#ifdef MYDLL // 用来导出函数
#define DLLVLC_API __declspec(dllexport)
#else // 用来标识为导入函数,对于引用该头文件的外部模块来说dllimport这个标记对编译优化有作用
#define DLLVLC_API __declspec(dllimport)
#endif
DllEntry.h代码
#pragma once
#ifdef MYDLL // 用来导出函数
#define DLLVLC_API __declspec(dllexport)
#else // 用来标识为导入函数,对于引用该头文件的外部模块来说dllimport这个标记对编译优化有作用
#define DLLVLC_API __declspec(dllimport)
#endif
#include <iostream>
#include <vector>
#include <stdio.h>
#include "string"
#include "function1.h"
#include <Halcon.h>
#include <HalconCpp.h>
using namespace HalconCpp;
namespace TestVLCDLL
{
extern "C"
{
DLLVLC_API int myAddFunction_interface(int a, int b);
DLLVLC_API int mySubtractFunction_interface(int a, int b);
DLLVLC_API int TransferHobj_Test_interface(mStruct Struct1);
}
}
DllEntry.cpp代码
#include "pch.h"
#include "DllEntry.h"
#include <fstream>
#include <thread>
#include <mutex>
using namespace std;
//声明一个线程锁,用于做线程同步
std::mutex mutexx1, mutexx2;
DLLVLC_API int TestVLCDLL::myAddFunction_interface(int a, int b)
{
mutexx1.lock();
function1 f;
return f.add(a, b);
mutexx1.unlock();
}
DLLVLC_API int TestVLCDLL::mySubtractFunction_interface(int a, int b)
{
mutexx2.lock();
function1 f;
return f.subtract(a, b);
mutexx2.unlock();
}
DLLVLC_API int TestVLCDLL::TransferHobj_Test_interface(mStruct Struct1)
{
function1 f;
return f.TransferHobj_Test(Struct1);
}
这段代码的含义是,MYDLL是在我自己的项目属性里面提前定义了,所以项目编译的时候会编译DLLVLC_API __declspec(dllexport),而上位机调用的时候没有提前定义MYDLL,上位机代码编译的时候就会编译DLLVLC_API __declspec(dllimport)。说是dllimport这个标记对编译优化有作用。不过经过我的项目实测,其实不写头文件中那一段代码,直接按照下面的代码写,也是正常编译运行的
extern “C” _declspec (dllexport) int TransferHobj_Test_interface(mStruct Struct1);
二、新建C++控制台程序TestDll,测试封装的dll。
2.1 创建项目解决方案
2.2 把封装好的东西全部放入TestDll的执行目录下,包含以下文件 Dll1.dll,Dll1.lib,DllEntry.h,function1.h。
然后配置C/C++常规附加包含目录,链接器常规附加库目录,链接器输入附加依赖项。
main()调用dll代码
int main()
{
//引用Dll封装库的命名空间
using namespace TestVLCDLL;
int ret = TestVLCDLL::myAddFunction_interface(1,2);
ret = mySubtractFunction_interface(10,5);
//测试C++封装的函数
int a = 0;
HObject img;
ReadImage(&img,"F:\\SanYuan_Image\\DaTu20221102-1\\1\\0.bmp");
double Area = 1;
mStruct struct1 =
{
//输入参数
10,
img,
65,
100,
//输出参数
Area
};
a = TestVLCDLL::TransferHobj_Test_interface(struct1);
}