当前位置: 代码迷 >> 综合 >> C++生成dll,并且加载dll进行测试
  详细解决方案

C++生成dll,并且加载dll进行测试

热度:99   发布时间:2023-10-20 19:13:23.0

这个月学习了很多内容,而且还各不相关。特此记录一下如何生成dll,如何使用dll。

生成dll

新建win32控制台应用程序项目,点击dll项目,然后点击空项目。

首先我们肯定需要写好自己的类。

class FlowNet :public Model_Loader_Base {public:FlowNet() {build_flow_map(colorwheel, ncols);};Mat flowImage;bool predict(const vector<std::pair<string, Tensor> >&) ;float colorwheel[55][3];unsigned char ncols;std::string output_node = "up_sampling2d_1/ResizeBilinear";public:void build_flow_map(float colorwheel[55][3], unsigned char &ncols);void flo2img(cv::Mat& flo, cv::Mat& img, float colorwheel[55][3], unsigned char ncols);Tensor input_1 = Tensor(DT_FLOAT, TensorShape({ 1,512,512,3 }));Tensor input_2 = Tensor(DT_FLOAT, TensorShape({ 1,512,512,3 }));void preProcessing(const Mat&, const Mat&);};

我这边定义一个FlowNet类。然后我们新建一个cpp源文件。包含我们定义类的头文件。

还要包含,一定要包含这个头文件。

#include <Windows.h>  // W是大写的

然后定义一个全局指针。

FlowNet* flownet = NULL;

我们需要设计自己需要使用的接口了,这个设计方式需要根据自己的情况。

比如博主要用这个类实现初始化模型,完成预测,和卸载模型,一共三个功能,所以需要设计三个接口。

extern "C" __declspec(dllexport) bool InitFlowNet(string pb_file)
{flownet = new FlowNet();if (NULL != flownet){std::cout << "successfully new a FlowNet class " << std::endl;}else{std::cout << "fail to new a FlowNet class... " << std::endl;}if (!flownet->init()) {cout << "fait to init flownet" << std::endl;return false;}else {return flownet->load(pb_file);}
}

第一个接口函数是InitFlowNet,在函数前面加上

 extern "C" __declspec(dllexport)

预测函数就不展示了,因为不通用。卸载接口是和初始化接口是必要的,因为new了指针,就必然对应delete嘛

extern "C" __declspec(dllexport) void ReleaseFlowNet()
{if (NULL != flownet){delete flownet;flownet = NULL;//showLog << "完成释放" << endl;}
}

然后CTRL+F5运行。没有错误的话,就可以在项目的x64的release下看到和项目名称相同的dll和lib文件了。(x64和release对应自己编译的环境)。

使用dll

使用dll的方式有两种,分为静态调用和动态调用,(是这么叫吧,我不是专业学C++的)。我仅介绍动态调用,因为真的好用。

新建一个新的空项目(直接点击空项目),把上一步生成的dll放到项目工程里面,和源文件cpp文件一个目录下。然后我们新建一个源.cpp文件。

还是要包含

#include <windows.h>

之后需要定义接口的函数指针。我仅展示我之前展示的初始化接口和卸载接口。

typedef bool(*pInit)(string);
typedef void(*pRelease)();

然后设置这些指针指向NULL;

pInit pInitFun = NULL;
pRelease pReleaseFun = NULL;

那么pInitFun和pReleaseFun就是我们接下来调用的函数了。但是现在还不能直接用。

接下来导入dll

HINSTANCE hdll = LoadLibrary(" your dll name .dll");
if( !hdll)
{cout<<"fail to import dll<<endl;
}
else 
{pInitFun = (pInit)GetProcAddress(hdll,"InitFlowNet");pReleaseFun = (pRelease)GetProcAddress(hdll."ReleaseFlowNet");
}

然后pInitFun和pReleaseFun就指向我们在生成dll的文件中定义的接口了。之后就可以愉快的使用这两个函数在任何win电脑上了。

错误记录

如果导入dll失败,用GetLastError发现输出126,则说明生成的dll使用了另一个dll,而那个dll没有拷贝到当前项目中。

  相关解决方案