10.Visual Studio动态加载_哔哩哔哩_bilibili
1.工程组织
① researcher.cpp
#include "nn/nn.h"
#include "nn/factory.h"
#include "nn/factory_impl/factory_impl.h"
#include <iostream>
int main()
{
int ret = 0;
factory_i* fct = new factory_impl();
auto nn = fct->create_nn("dnn");
const char* data_from_somewhere = "A B C D";
ret = nn->train(data_from_somewhere, strlen(data_from_somewhere));
if (0 != ret)
std::cout << "failed to train the model." << std::endl;
const char* model_from_somewhere = "k=10;b=200";
ret = nn->forward(model_from_somewhere, strlen(model_from_somewhere));
if (0 != ret)
std::cout << "failed to forward the model." << std::endl;
delete nn; nn = nullptr;
delete fct; fct = nullptr;
return 0;
}
② nn.h
#ifndef __NN_H__
#define __NN_H__
class nn_i
{
public:
virtual ~nn_i() = default;
virtual int train(const char* data, size_t data_size) = 0;
virtual int forward(const char* model, size_t model_size) = 0;
};
#endif
(1)cnn.h
#ifndef __CNN_H__
#define __CNN_H__
#include "nn/nn.h"
#include <string>
#include <iostream>
class cnn : public nn_i
{
public:
explicit cnn(const char* conf)
: conf_(conf)
{
}
virtual ~cnn() = default;
virtual int train(const char* data, size_t data_size) override
{
std::cout << "train with Convolution and Pooling layer in cnn." << std::endl;
return 0;
}
virtual int forward(const char* model, size_t model_size) override
{
std::cout << "forward with Convolution and Pooling layer in cnn." << std::endl;
return 0;
}
public:
std::string conf_;
};
#endif
(2)dnn.h
#ifndef __DNN_H__
#define __DNN_H__
#include "nn/nn.h"
#include <string>
#include <iostream>
class dnn : public nn_i
{
public:
explicit dnn(const char* conf)
: conf_(conf)
{
}
virtual ~dnn() = default;
virtual int train(const char* data, size_t data_size) override
{
std::cout << "train with fully connected layer in dnn." << std::endl;
return 0;
}
virtual int forward(const char* model, size_t model_size) override
{
std::cout << "forward with fully connected layer in dnn." << std::endl;
return 0;
}
public:
std::string conf_;
};
#endif
(3)rnn.h
#ifndef __RNN_H__
#define __RNN_H__
#include "nn/nn.h"
#include <string>
#include <iostream>
class rnn : public nn_i
{
public:
explicit rnn(const char* conf)
: conf_(conf)
{
}
virtual ~rnn() = default;
virtual int train(const char* data, size_t data_size) override
{
std::cout << "train with Convolution and Pooling layer in cnn." << std::endl;
return 0;
}
virtual int forward(const char* model, size_t model_size) override
{
std::cout << "forward with Convolution and Pooling layer in cnn." << std::endl;
return 0;
}
public:
std::string conf_;
};
#endif
③ factory.h
#ifndef __FACTORY_H__
#define __FACTORY_H__
class nn_i;
class factory_i
{
public:
virtual ~factory_i() = default;
virtual nn_i* create_nn(const char* name) = 0;
};
#endif
(1)factory_impl.h
#ifndef __FACTORY_IMPL_H__
#define __FACTORY_IMPL_H__
#include "nn/factory.h"
class nn_i;
class factory_impl : public factory_i
{
public:
explicit factory_impl();
virtual ~factory_impl() = default;
virtual nn_i* create_nn(const char* name) override;
};
#endif
(2)factory_impl.cpp
#include "factory_impl.h"
#include "nn/network_impl/rnn.h"
#include "nn/network_impl/cnn.h"
#include "nn/network_impl/dnn.h"
#include <string>
factory_impl::factory_impl()
{
}
nn_i* factory_impl::create_nn(const char* name)
{
if (nullptr == name)
return nullptr;
const char* conf_from_somewhere = "Hero=Iron Man";
auto str_name = std::string(name);
if (str_name == "dnn")
return new dnn(conf_from_somewhere);
else if (str_name == "rnn")
return new rnn(conf_from_somewhere);
else if (str_name == "cnn")
return new cnn(conf_from_somewhere);
return nullptr;
}
2.动态加载
现在要把上面的工程改成动态加载:
① network_loader.cpp
#include "nn/nn_api.h"
#include <iostream>
#include <windows.h>
static const char* filename = "libnn.dll";
int main()
{
/* 1. 加载DLL到当前的地址空间 */
HMODULE handle = LoadLibraryA(filename);
if (!handle)
{
std::cout << "failed to load library: "
<< filename << std::endl;
return -1;
}
/* 2. 获取dll导出函数地址 */
auto func_init_network
= (Proc_InitNetwork)GetProcAddress(handle, "InitNetwork");
auto func_fini_network
= (Proc_FiniNetwork)GetProcAddress(handle, "FiniNetwork");
auto func_train_network
= (Proc_TrainNetwork)GetProcAddress(handle, "TrainNetwork");
auto func_infer_network
= (Proc_InferNetwork)GetProcAddress(handle, "InferNetwork");
/* 3. 调用dll完成我们的功能 */
func_init_network("dnn");
const char* data_from_somewhere = "A B C D";
func_train_network(data_from_somewhere, strlen(data_from_somewhere));
const char* model_from_somewhere = "k=10;b=200";
func_infer_network(model_from_somewhere, strlen(model_from_somewhere));
func_fini_network();
/* 4. 释放dll */
FreeLibrary(handle);
return 0;
}
② api
(1)nn_api.h
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
_declspec(dllexport) int __stdcall InitNetwork(const char* which);
_declspec(dllexport) int __stdcall FiniNetwork();
_declspec(dllexport) int __stdcall TrainNetwork(const char* data, size_t size);
_declspec(dllexport) int __stdcall InferNetwork(const char* model, size_t size);
#ifdef __cplusplus
}
#endif
(2)nn_api.cpp
#include "nn_api.h"
#include "nn/factory_impl/factory_impl.h"
#include "nn/factory.h"
#include "nn/nn.h"
#include <iostream>
static nn_i* g_nn = nullptr;
int InitNetwork(const char* which)
{
factory_i* fct = new factory_impl();
g_nn = fct->create_nn(which);
delete fct;
return 0;
}
int FiniNetwork()
{
delete g_nn; g_nn = nullptr;
return 0;
}
int TrainNetwork(const char* data, size_t size)
{
if (!g_nn)
return -1;
int ret = g_nn->train(data, size);
if (0 != ret)
std::cout << "failed to train the model." << std::endl;
return 0;
}
int InferNetwork(const char* model, size_t size)
{
if (!g_nn)
return -1;
int ret = g_nn->forward(model, size);
if (0 != ret)
std::cout << "failed to infert the network." << std::endl;
return 0;
return 0;
}
③ nn.h (自此及往下部分 与之前的一致)
#ifndef __NN_H__
#define __NN_H__
class nn_i
{
public:
virtual ~nn_i() = default;
virtual int train(const char* data, size_t data_size) = 0;
virtual int forward(const char* model, size_t model_size) = 0;
};
#endif
(1)cnn.h
#ifndef __CNN_H__
#define __CNN_H__
#include "nn/nn.h"
#include <string>
#include <iostream>
class cnn : public nn_i
{
public:
explicit cnn(const char* conf)
: conf_(conf)
{
}
virtual ~cnn() = default;
virtual int train(const char* data, size_t data_size) override
{
std::cout << "train with Convolution and Pooling layer in cnn." << std::endl;
return 0;
}
virtual int forward(const char* model, size_t model_size) override
{
std::cout << "forward with Convolution and Pooling layer in cnn." << std::endl;
return 0;
}
public:
std::string conf_;
};
#endif
(2)dnn.h
#ifndef __DNN_H__
#define __DNN_H__
#include "nn/nn.h"
#include <string>
#include <iostream>
class dnn : public nn_i
{
public:
explicit dnn(const char* conf)
: conf_(conf)
{
}
virtual ~dnn() = default;
virtual int train(const char* data, size_t data_size) override
{
std::cout << "train with fully connected layer in dnn." << std::endl;
return 0;
}
virtual int forward(const char* model, size_t model_size) override
{
std::cout << "forward with fully connected layer in dnn." << std::endl;
return 0;
}
public:
std::string conf_;
};
#endif
(3)rnn.h
#ifndef __RNN_H__
#define __RNN_H__
#include "nn/nn.h"
#include <string>
#include <iostream>
class rnn : public nn_i
{
public:
explicit rnn(const char* conf)
: conf_(conf)
{
}
virtual ~rnn() = default;
virtual int train(const char* data, size_t data_size) override
{
std::cout << "train with Convolution and Pooling layer in cnn." << std::endl;
return 0;
}
virtual int forward(const char* model, size_t model_size) override
{
std::cout << "forward with Convolution and Pooling layer in cnn." << std::endl;
return 0;
}
public:
std::string conf_;
};
#endif
④ factory.h
#ifndef __FACTORY_H__
#define __FACTORY_H__
class nn_i;
class factory_i
{
public:
virtual ~factory_i() = default;
virtual nn_i* create_nn(const char* name) = 0;
};
#endif
(1)factory_impl.h
#ifndef __FACTORY_IMPL_H__
#define __FACTORY_IMPL_H__
#include "nn/factory.h"
class nn_i;
class factory_impl : public factory_i
{
public:
explicit factory_impl();
virtual ~factory_impl() = default;
virtual nn_i* create_nn(const char* name) override;
};
#endif
(2)factory_impl.cpp
#include "factory_impl.h"
#include "nn/network_impl/rnn.h"
#include "nn/network_impl/cnn.h"
#include "nn/network_impl/dnn.h"
#include <string>
factory_impl::factory_impl()
{
}
nn_i* factory_impl::create_nn(const char* name)
{
if (nullptr == name)
return nullptr;
const char* conf_from_somewhere = "Hero=Iron Man";
auto str_name = std::string(name);
if (str_name == "dnn")
return new dnn(conf_from_somewhere);
else if (str_name == "rnn")
return new rnn(conf_from_somewhere);
else if (str_name == "cnn")
return new cnn(conf_from_somewhere);
return nullptr;
}