2019年6月6日 星期四

動態加載(explicit linking) DLL的注意事項


─ 問題描述:
一開始測試載dll的時候,一直都載不進程式中,用depends22_86這個軟體檢查dll 檔,確認是否有我定義的函式進入點,檢查結果是有的。

DLL的程式碼如下:
VC14Dll.h
#pragma once
#include "opencv2\opencv.hpp"
#include <windows.h>
#ifdef VC14DLL_EXPORTS
#define VC14DLL_EXPORTS __declspec(dllexport)
#else
#define VC14DLL_EXPORTS __declspec(dllimport)
#endif //  DLLEXPORT
VC14DLL_EXPORTS int Test(cv::Mat input);
VC14DLL_EXPORTS void Test2();
VC14Dll.cpp
// VC14Dll.cpp : 定義 DLL 應用程式的匯出函式。
//
#include "stdafx.h"
#include "VC14Dll.h"
#include "opencv2\opencv.hpp"
VC14DLL_EXPORTS int Test(cv::Mat input)
{
        try {
               int threshval = 100;
               cv::Mat grayImg;
               cv::cvtColor(input, grayImg, cv::COLOR_BGR2GRAY);
               cv::Mat binaryImg = threshval < 128 ? (grayImg < threshval) : (grayImg > threshval);
               cv::Mat labelImage;
               int nLabels = cv::connectedComponents(binaryImg, labelImage, 8);
               return 5;
               //std::cout << nLabels << std::endl;
        }
        catch (cv::Exception err) {
               return -1;
        }
        catch (...) {
               return -1;
        }
        return -1;
}
VC14DLL_EXPORTS void Test2()
{
        try {
               std::cout << "yo~~~~~" << std::endl;
        }
        catch (...) {
        }
}

─ 想法:
之前都是找英文的資訊,這次直接用中文找,看到了一篇文章



裡面有用extern "C",當下我就想:「LoadLibrary是不是C的runtime library,所以少了這個就無法呼叫了」

─ 解決方法:
在標頭檔宣告時,加上extern "C"就可以呼叫成功了!



程式碼如下:
VC14Dll.h
#pragma once
#include "opencv2\opencv.hpp"
#include <windows.h>
#ifdef VC14DLL_EXPORTS
#define VC14DLL_EXPORTS __declspec(dllexport)
#else
#define VC14DLL_EXPORTS __declspec(dllimport)
#endif //  DLLEXPORT
extern "C" VC14DLL_EXPORTS int Test(cv::Mat input);
extern "C" VC14DLL_EXPORTS void Test2();

VC14Dll.cpp
// VC14Dll.cpp : 定義 DLL 應用程式的匯出函式。
//
#include "stdafx.h"
#include "VC14Dll.h"
#include "opencv2\opencv.hpp"
int Test(cv::Mat input)
{
        try {
               int threshval = 100;
               cv::Mat grayImg;
               cv::cvtColor(input, grayImg, cv::COLOR_BGR2GRAY);
               cv::Mat binaryImg = threshval < 128 ? (grayImg < threshval) : (grayImg > threshval);
               cv::Mat labelImage;
               int nLabels = cv::connectedComponents(binaryImg, labelImage, 8);
               return 5;
               //std::cout << nLabels << std::endl;
        }
        catch (cv::Exception err) {
               return -1;
        }
        catch (...) {
               return -1;
        }
        return -1;
}
void Test2()
{
        try {
               std::cout << "yo~~~~~" << std::endl;
        }
        catch (...) {
        }
}

─ 參考資料
[2][C++ 小學堂] 如何建立 export 的 dll 與如何動態呼叫 export 的 dll 
[3] C++ Dynamic Link Libraries : Creating a DLL and Implicit Linking
[4]C++ Dynamic Link Libraries : Part 2 (Explicit Linking)

沒有留言:

張貼留言