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;
} 
                


















