Существует несколько различных способов создания DLL. Самый простой и прямой способ — использовать проект библиотеки динамической компоновки (DLL), поставляемый с VS, для инкапсуляции соответствующих функций в класс, затем экспортировать несколько методов интерфейса и сгенерировать DLL. после успешной компиляции его можно вызвать в другом месте, как обычную стороннюю библиотеку после настройки.
01、Создать DLL
Сначала откройте VS и создайте пустой проект DLL. Откройте мастер рабочего стола VS следующим образом:
Создать проект библиотеки ссылок DLL
Затем добавьте файл mytest.h в заголовочный файл и добавьте следующий код:
#pragma once
#ifdef _DLL_EXPORTS
#define DLL_API _declspec(dllexport)
#else
#define DLL_API _declspec(dllimport)
#endif
#include <opencv2/opencv.hpp>
//==========Экспорт функции C++, вызов интерфейса============
class DLL_API MyTestDLL {
public:
int addData(int a, int b);
~MyTestDLL();
};
Затем добавьте файл mytest.cpp в исходный файл и добавьте следующий код:
#define _DLL_EXPORTS
#include <mytest.h>
MyTestDLL::~MyTestDLL() {
std::cout << "destory instance done!" << std::endl;
}
int MyTestDLL::addData(int a, int b) {
int sum = 0;
sum = a + b;
std::cout << "sum: " << sum << std::endl;
return sum;
}
Компиляция прошла успешно, и на дисплее появится следующее:
02、тестовая программа DLL
Создайте тестовую программу для проверки DLL. Создайте новый пустой консольный проект, добавьте файл main.cpp в исходный файл, а затем добавьте следующий код:
#include "opencv2/opencv.hpp"
#include "mytest.h"
int main(int argc, char** argv) {
std::cout << "test mydll..." << std::endl;
std::shared_ptr<MyTestDLL> mydll(new MyTestDLL());
int sum = mydll->addData(3, 5);
std::cout << "DLL invoke result : " << sum << std::endl;
return 0;
}
Результаты бега следующие:
Тест DLL обнаружения объектов YOLOv8
Используя тот же метод, основанный на структуре библиотеки моделей глубокого обучения ONNXRUNTIME, я немного изменил предыдущий код C++ для обнаружения объектов ONNXRUNTIME + YOLOv8 и инкапсулировал класс рассуждений для обнаружения объектов YOLOv8 в виде DLL, который поддерживает вызовы интерфейсов C++ и C#. Код вызова клиента следующий:
#include "yolov8_infer.h"
#include <iostream>
#include <fstream>
std::string label_map = "D:/python/yolov5-7.0/classes.txt";
int main(int argc, char** argv) {
std::string names = "10:bike";
int pos = names.find_first_of(":");
std::cout << names.substr(0, pos) << " -->> " << names.substr(pos + 1) << std::endl;
std::vector<std::string> classNames;
std::ifstream fp(label_map);
std::string name;
while (!fp.eof()) {
getline(fp, name);
if (name.length()) {
classNames.push_back(name);
}
}
fp.close();
// std::shared_ptr<YOLOv5ORTDetector> detector(new YOLOv5ORTDetector());
std::shared_ptr<YOLOv8ORTDetector> detector(new YOLOv8ORTDetector());
detector->initConfig("D:/python/my_yolov8_train_demo/yolov8n.onnx", 640, 640, 0.25f, 0.5);
cv::VideoCapture capture("D:/images/video/sample.mp4");
cv::Mat frame;
std::vector<DetectResult> results;
while (true) {
bool ret = capture.read(frame);
if (frame.empty()) {
break;
}
int64 start = cv::getTickCount();
detector->detect(frame, results);
float fps = static_cast<float>(cv::getTickFrequency()) / (cv::getTickCount() - start);
cv::putText(frame, cv::format("FPS: %.2f", fps), cv::Point(50, 50), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(255, 0, 255), 2, 8);
for (DetectResult dr : results) {
cv::Rect box = dr.box;
cv::putText(frame, classNames[dr.classId], cv::Point(box.tl().x, box.tl().y - 10), cv::FONT_HERSHEY_SIMPLEX, .5, cv::Scalar(0, 0, 0));
}
cv::imshow("YOLOv8 + ONNXRUNTIME - Демонстрация экспорта DLL", frame);
char c = cv::waitKey(1);
if (c == 27) { // ESC покидать
break;
}
// reset for next frame
results.clear();
}
return 0;
}
Рабочий скриншот выглядит следующим образом: