顯示具有 dll檔 標籤的文章。 顯示所有文章
顯示具有 dll檔 標籤的文章。 顯示所有文章

2020年10月31日 星期六

winform 在dll中的usercontrol只能用Any CPU或是x86編譯

 [問題描述]

現在有兩個專案,一個是dll的專案,裡面有usercontrol,
另一個是dll(usercontrol)的測試專案,
兩個編譯平台都是Release x64。
在測試專案winform的designer中,
將dll中的Usercontrol元件拉到form上,
出現「Failed to load toolbox item. It will be removed from the toolbox」,如下圖

dll的編譯設定如下圖


測試專案的編譯設定如下圖

2020年4月18日 星期六

用「附加至處理程序(Attach to Process ...)」Debug

今天來分享一個好用的dll debug方式!

之前在上海幫忙的時候,
jim就有教過我們用「附加至處理程序」(Attach to Process ...),
並跟我們說這個功能很好用,
不過當時並沒有體會到這個功能好用的地方。

在上海負責的案子比較特殊,
是用CCF (CIM Control Framework)的框架,
而那個框架是用分散式架構,分程三支程式;分別放在三台電腦中,
重點是開啟是有順序的。
若用一般debug的手法會很難debug,
直接按下F5,然後下斷點,會不好debug,
除了程式啟動的順序外,
彼此的dll都有一些關聯,這樣做可能會出問題。
所以一直以為,
那個「附加至處理程序」(Attach to Process ...),
是因為CCF的架構不好debug才使用的。

但今天才發現,這個功能真的爆幹好用!
一般來說,如果方案較大,裡面包含有dll的專案,
在debug dll時,就要將dll設成啟始專案,

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();

2019年5月26日 星期日

[log book] 解決VS2008 exe使用VS2015的dll並delete VS2015 dll new出來的變數導致程式崩潰

[問題描述]
延續《 [log book] 解決演算法結果接口介面化的問題 ─ 要改變指標,請用指標的指標(雙重指標)》之後,又遇到了一個問題,由於我的dll是使用VS2015寫的,但機台的子機程式是用VS2008寫的,當我在exe中釋放的時候,就會出問題。
下圖中,要釋放的記憶體空間result是我在exe中宣告出的記憶體空間,作用是接dll中演算法的運算結果的


[解題思路]
讀到zj510大大的博客《跨DLL的内存分配释放问题 Heap corruption》,雖然裡面在探討的議題與我遇到的稍微不一樣,但看到z大所寫到的:「在一个DLL里面分配内存,然后在DLL的调用者EXE那里释放内存。当DLL和EXE里面有一个是使用MT连接CRT的时候就有问题。如果DLL和EXE都使用MD,那么就没有问题。」,我突然想到:「我應該在dll中釋放dll宣告的記憶體」。

[解決方法]
在dll檔的類別及介面(interface)中,多宣告一個方法釋放dll的記憶體空間的方法 ─ releaseResult
介面的宣告如下
#pragma once
#include "HsStruct.h"
typedef void Result;
class HInspectAlgoInterface
{
public:
        virtual ~HInspectAlgoInterface() { ; }
        virtual bool inspect(ImageParam imgParam, wdb_type *wd, hole_type *md) = 0;
        //virtual bool getResult(std::string Type, int *Num, Result **Ret) = 0;
        virtual bool getResult(char* Type, int *Num, Result **Ret) = 0;
        virtual bool releaseResult(Result **Ret) = 0;
};


releaseResult的定義如下
bool IrrBurCheckAlgo::releaseResult(Result **Ret)
{
        try {
               if (*Ret){
                       delete[] * Ret;
                       *Ret = NULL;
               }
               return true;
        }
        catch (std::exception ex) {
               return false;
        }
}



執行結果如下:

結論:dll new出來的記憶體位置最好由dll自己釋放

不過後來我有發現:若使用的VS 版本一樣,且都是用MD,就不會發生這個問題

下面提供測試版的程式碼:

VS 2015 dll的程式碼:(用MD編譯)
HInspectAlgoInterface.h
#pragma once
#include "HsStruct.h"
typedef void Result;
class HInspectAlgoInterface
{
public:
        virtual ~HInspectAlgoInterface() { ; }
        virtual bool inspect(ImageParam imgParam, wdb_type *wd, hole_type *md) = 0;
        virtual bool getResult(char* Type, int *Num, Result **Ret) = 0;
        virtual bool releaseResult(Result **Ret) = 0;
};

HsStruct.h
#ifndef _HSSTRUCT_H_
#define _HSSTRUCT_H_

typedef struct {
        long id;
        long chip;
        long no;
        long Left;
        long Top;
        long width;
        long height;
}wdb_type;

typedef struct{
        long hole_size;
        long hole_x;
        long hole_y;
        long hole_dx;
        long hole_dy;
}hole_type;

typedef struct{
        unsigned char *Src;
        int Width;
        int Height;
} ImageParam;

2017年8月26日 星期六

使用Visual Studio 2015 C++建立dll檔 ─ dll檔的建立

什麼是dll?

dll是 Dynamic-Link Library的縮寫,中文翻譯為「動態連結函式庫」,在windows 的環境下,副檔名是「.dll」;在linux的環境下,副檔名是「.xo」。dll檔的概念有點像是函式,但與函式不同,函式在編譯時就會一起被編譯,而dll檔是在程式之外的函式,在程式執行的階段若有用到dll中的函式,dll檔才會被載入、執行。[1]
使用dll檔可以節省應用程式所需的磁碟的大小及記憶體空間,而且移植性高,有利於將程式模組化,若有其他支程式需要用到dll檔中的函式,載入dll檔即可。dll檔還有另一個作用,就是可以隱藏函式細節,如果有人要某個功能,可以只將dll檔給對方,並將函式接口告訴對方,而對方無法一窺作者的寫法。