人工智能→计算机视觉经典程序开发实现2:在工程项目程序开发过程中的图像算法类、算子封装继承程序编写方法及调试
今天我们来学会一个工程实践中的实用技能,该技能是身为人工智能领域算法、软件工程师等必备技能:也就是如何将一个编写好的算法程序函数进行封装实现,尤其是存在继承类关系的算子函数进行封装。初步入门该领域的读者可能疑惑了,什么是封装?熟悉面向对象编程的读者可能会首先想到:封装、继承和多态是面向对象开发的三大特性;而我们今天的实用技能涉及到其中两方面特性封装和继承。其实很容易理解:所谓封装就是可以通俗的理解为一种常规的加密技术,我们通常开发的算法函数算子能够看到函数名和函数体,也就是能看到算子函数的源码,实际的工程实践中在我们进行集成工作时,可能我们希望开发的算子函数在使用时只需要开放函数名和参数能够使用就行了,算子函数的函数体也就是函数源码部分进行封装后集成的用户非必要看到,只有开发人员能够从源程序看到源码的这样一种技术实现加密方式。该技术实现一定程度上在工程实践中将算法函数算子的开发成果进行加密保护,只在特定情况由开发人员进行查看和维护的技术实现方式,该方式具有安全性、灵活性和可维护性的平衡,简化代码复杂度,即高内聚低耦合。封装对于算法来讲就好比加密狗对于软件系统,都是一种对开发出来的软件算法进行知识产权保护的一种技术方法。
为了更好的掌握该项技能,我们采用三步来实现,由浅到深,由易到难,逐步深刻理解并且掌握该技能。第一步:我们先学习个简单的函数算子的封装,这里我们采用一个简单的函数运算算法算子(加法+减法-乘法*除法/四则运算算法)作为示例重点讲解如何对其进行封装的技能,这样更容易理解和掌握封装的知识点技能,简单的算子封装技能掌握了,那么具有难度的函数算子封装也就掌握了方法,再结合实践练习练习就会了,第二步我们再学习含有类函数的及其函数算子的封装,第三步我们最后再掌握带有继承类的函数算子的封装。
函数算子封装
1、编写个函数算子程序源码例如四则运算:加法、减法、乘法、除法
这里以C++编程语言示例说明:C#/Python同样可以相应封装方法。
//创建加减乘除运算算法函数算子源码
int algorithm_Add(int a, int b) {
return a + b;
}
int algorithm_Sub(int a, int b) {
return a - b;
}
int algorithm_Mul(int a, int b) {
return a * b;
}
int algorithm_Div(int a, int b) {
return a/b;
}
2、编写封装算法程序对前面写好的四则运算函数算法进行封装为算子
(1)、创建封装函数算子工程操作步骤:新建项目→搜索DLL 选择创建动态链接库→工程命名:fengzhuang_DLL1,位置存放,完成创建。
动态链接库
工程命名、保存地址,完成创建。
(2)、生成初始工程,在<dllmain.cpp>文件处拷贝写好的算法源码,在<pch.h>文件中编写需要进行封装的函数算子名称和输入输出参数,语句格式为《extern “C” __declspec(dllexport) 函数类型 函数名(输入参数,输出参数)》,表明封装对象为<函数类型 函数名(输入参数,输出参数)>的函数算子。
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//创建加减乘除运算算法函数算子
int algorithm_Add(int a, int b) {
return a + b;
}
int algorithm_Sub(int a, int b) {
return a - b;
}
int algorithm_Mul(int a, int b) {
return a * b;
}
int algorithm_Div(int a, int b) {
return a / b;
}
// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
#ifndef PCH_H
#define PCH_H
// 添加要在此处预编译的标头
#include "framework.h"
//写需要封装的函数算子名称及参数
extern "C" __declspec(dllexport) int algorithm_Add(int a, int b);
extern "C" __declspec(dllexport) int algorithm_Sub(int a, int b);
extern "C" __declspec(dllexport) int algorithm_Mul(int a, int b);
extern "C" __declspec(dllexport) int algorithm_Div(int a, int b);
#endif //PCH_H
(3)点击生成→生成解决方案,完成加减乘除四则运算的函数算子封装,得到生成文件供后续使用。
3、写个测试程序引用前面封装好的四则运算算子函数,实现加减乘除四则运算功能。
// test_FengzhuangDLL_ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include <iostream>
using namespace std;
#include "pch.h"
int main()
{
//调试四则运算函数算法算子功能
//调试加法函数算子功能
cout << algorithm_Add(2, 5) << endl;
//调试减法函数算子功能
cout << algorithm_Sub(5, 2) << endl;
//调试乘法函数算子功能
cout << algorithm_Mul(5, 2) << endl;
//调试除法函数算子功能
cout << algorithm_Div(6, 3) << endl;
std::cout << "Hello World!\n";
system("pause");
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
如图创建调试工程测试封装的函数算子功能时需要获取到三个文件:头文件<pch.h>(在动态库生成工程中找到),动态链接库文件<fengzhuang_Dll1.dll>,静态链接库文件<fengzhuang_Dll1.lib>;头文件添加到函数头文件引用处,动静态链接库放置到工程目录里面,同时配置环境变量:头文件,库文件;运行程序看函数算子运行结果。
我们到这里就完成了《三步学会函数算子封装及继承类封装》的第一步:简单的四则运算算法函数算子封装的程序实现方法及操作讲解,该《三步学会函数算子封装及继承类封装》计划后续每一步用一个帖子来完成讲述。现在大家是否也看到了一个有趣的现象:编写的程序中并没有看到四则运算的函数定义也就是源码,只是引用了四则运算的函数名和输入输出参数类型,然后就通过添加头文件、环境变量配置动静态链接库的方式得到了这个四则运算的运行结果。读者朋友们,这个就是封装的神奇之处:把我们写的源程序中的函数算子数据通过封装保密的方式写到了我们动静态链接库文件中,从而在我们使用时候只需要通过添加头文件对函数算子说一个声明,动静态链接库添加路径,我们就能实现函数的调用,正常的使用函数算法了。看到这里大家是否就更加理解了,封装同时还让程序算法算子集成开发更加简洁,函数算子方法作为知识成果受到保密保护,同时实现了程序开发过程中高内聚,低耦合的特点,有利于程序算法的管理维护工作。
参考资料
1、动静态链接库封装方法