Escribí un artículo sobre el paquete DLL de C++ anteriormente, aquí hay un suplemento.
1. No diré más sobre cómo configurar las bibliotecas halcon y opencv, el artículo anterior lo presentó en detalle. A continuación se describe lo que se agrega al paquete.
1.1 Primero cree la clase function1 y escriba los códigos function.h y function1.cpp.
código 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);
};
código 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 Cree DllEntry.h y DllEntry.cpp respectivamente como clases de interfaz de llamada de computadora host, abra las propiedades del proyecto, busque el preprocesador C/C++ e ingrese la definición del preprocesador. Agregue MYDLL en la parte inferior. Luego edite los códigos DllEntry.h y DllEntry.cpp. Agregue el siguiente código al archivo de encabezado y luego escriba otro código
#ifdef MYDLL // 用来导出函数
#define DLLVLC_API __declspec(dllexport)
#else // 用来标识为导入函数,对于引用该头文件的外部模块来说dllimport这个标记对编译优化有作用
#define DLLVLC_API __declspec(dllimport)
#endif
Código 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);
}
}
Código 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);
}
El significado de este código es que MYDLL se define de antemano en las propiedades de mi propio proyecto, por lo que DLLVLC_API __declspec(dllexport) se compilará cuando se compile el proyecto, pero MYDLL no se define de antemano cuando la computadora host llama, cuando la computadora host se compila el código DLLVLC_API __declspec(dllimport) se compilará. Se dice que el indicador dllimport tiene un efecto en la optimización de la compilación. Sin embargo, después de la medición real de mi proyecto, de hecho, no escribo el código en el archivo de encabezado, sino que lo escribo directamente de acuerdo con el siguiente código, que también es
extern “C” _declspec (dllexport) int TransferHobj_Test_interface(mStruct Struct1);
2. Crear una nueva consola C++ El programa TestDll prueba la dll empaquetada.
2.1 Cree una solución de proyecto
2.2 Coloque todos los elementos empaquetados en el directorio de ejecución de TestDll, incluidos los siguientes archivos Dll1.dll, Dll1.lib, DllEntry.h, function1.h.
A continuación, configure los directorios de inclusión adicionales generales de C/C++, los directorios de bibliotecas adicionales generales del enlazador y las dependencias adicionales de entrada del enlazador.
main() llama al código 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);
}