以前 C++ パッケージ DLL についての記事を書きましたが、補足です。
1. 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);
2. 新しい C++ コンソールを作成する プログラム TestDll は、パッケージ化された DLL をテストします。
2.1 プロジェクト ソリューションを作成します。
2.2 次のファイル Dll1.dll、Dll1.lib、DllEntry.h、function1.h を含む、パッケージ化されたすべてのものを TestDll の実行ディレクトリに置きます。
次に、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);
}