VC DLL学习
1.1 創(chuàng)建dll項(xiàng)目
1.2 為dll項(xiàng)目編寫(xiě)源文件
頭文件dllDemo.h
extern?"C"?_declspec(dllexport)?int?Sum(int?a,int?b);//加法函數(shù)。
extern?"C"?_declspec(dllexport)?int?Max(int?a,?int?b);//取較大值函數(shù)
extern?"C"?_declspec(dllexport)?int?Min(int?a,?int?b);//取較小值函數(shù) 源文件dllDemo.cpp
大氣象 #include?"dllDemo.h"
extern?"C"?_declspec(dllexport)int?Sum(int?a,?int?b)
{return?a+b;}
extern?"C"?_declspec(dllexport)int?Max(int?a,?int?b)
{
????if(a>=b)
????????return?a;
????else
????????return?b;
}
extern?"C"?_declspec(dllexport)int?Min(int?a,?int?b)
{
????if(a>=b)
????????return?b;
????else
????????return?a;
}
1.3 生成dll文件
編譯源文件,如果沒(méi)有出現(xiàn)錯(cuò)誤提示,那么,在項(xiàng)目文件根目錄的Debug文件夾內(nèi)會(huì)生成一個(gè)dll文件“dllDemo.dll”。
調(diào)用
新建了個(gè)MFC單對(duì)話(huà)框項(xiàng)目,
將“dllDemo.dll”和”dllDemo.lib”文件復(fù)制到本項(xiàng)目的Debug目錄下,
在VC工作空間的文件視圖下面將”dllDemo.lib”添加到項(xiàng)目中
在對(duì)話(huà)框頭文件添加引用:
//
#pragma?once
extern?"C"_declspec(dllimport)?int?Sum(int?a,int?b);
extern?"C"_declspec(dllimport)?int?Max(int?a,int?b);
extern?"C"_declspec(dllimport)?int?Min(int?a,int?b);
//?CFileOperDlg?對(duì)話(huà)框
class?CFileOperDlg?:?public?CDialog
{
//?構(gòu)造
public:
????CFileOperDlg(CWnd*?pParent?=?NULL);????//?標(biāo)準(zhǔn)構(gòu)造函數(shù)
//?對(duì)話(huà)框數(shù)據(jù)
????enum?{?IDD?=?IDD_FILEOPER_DIALOG?};
????protected:
????virtual?void?DoDataExchange(CDataExchange*?pDX);????//?DDX/DDV?支持
//?實(shí)現(xiàn)
protected:
????HICON?m_hIcon;
????//?生成的消息映射函數(shù)
????virtual?BOOL?OnInitDialog();
????afx_msg?void?OnSysCommand(UINT?nID,?LPARAM?lParam);
????afx_msg?void?OnPaint();
????afx_msg?HCURSOR?OnQueryDragIcon();
????DECLARE_MESSAGE_MAP()
public:
????CString?m_info;
};
?
調(diào)用:
CString?str;int?c=Sum(4,5);??
//c=Max(5,6);??
//c=Min(5,6);
str.Format("%d",c);
AfxMessageBox(str);
?
調(diào)試
直接運(yùn)行,選擇一個(gè)調(diào)用dll的exe確定之后,就可以調(diào)試了,設(shè)置個(gè)斷點(diǎn)試試。
?
?
?
參考:
VC++的DLL應(yīng)用(含Demo演示)
作者:一點(diǎn)一滴的Beer?http://beer.cnblogs.com/
????? 在大學(xué)大一的時(shí)候?qū)W的是C,然后后來(lái)大二的時(shí)候?qū)I(yè)又開(kāi)了C++這個(gè)課程,然后再后來(lái)自己又自學(xué)了一點(diǎn)VC++,大三的時(shí)候也試著編寫(xiě)過(guò)一個(gè)MFC的最簡(jiǎn)單的窗口程序。到大四的時(shí)候,自己又做了一個(gè)GIS的項(xiàng)目,是用C#.NET來(lái)編寫(xiě)的,然后發(fā)現(xiàn)C#上手好容易,而且還大部分語(yǔ)法規(guī)則都沿用了C,C++的習(xí)慣,于是覺(jué)得C++實(shí)在是沒(méi)有一點(diǎn)優(yōu)勢(shì)可言啊。但這個(gè)暑假的實(shí)習(xí)經(jīng)歷又改變了我的觀點(diǎn):C++在寫(xiě)窗口程序雖然麻煩,但是卻什么能做,而且對(duì)比C#來(lái)說(shuō),對(duì)運(yùn)行環(huán)境的要求不高,不用像C#程序在安裝之前還要安裝100M多的運(yùn)行.NET環(huán)境。C++和C#各有優(yōu)缺,目前我對(duì)它們倆的定位是:C++用來(lái)寫(xiě)一些底層的程序,比如驅(qū)動(dòng),或者是一些算法類(lèi)型的函數(shù)接口,然后用C#來(lái)調(diào)用這些接口并進(jìn)行界面設(shè)計(jì)。如何函數(shù)的實(shí)現(xiàn)跨語(yǔ)言呢?顯然DLL是個(gè)很重要的內(nèi)容,故在此對(duì)VC++的DLL模塊進(jìn)行介紹。
1?用VC創(chuàng)建DLL動(dòng)態(tài)連接庫(kù)
?
1.1 創(chuàng)建dll項(xiàng)目
然后選擇“一個(gè)空的dll工程”,然后點(diǎn)擊“確定”便完成了“創(chuàng)建dll項(xiàng)目”的流程。
?
1.2 為dll項(xiàng)目編寫(xiě)源文件
新建兩個(gè)文件:dllDemo.h, dllDemo.cpp
在頭文件”dllDemo.h”中聲明三個(gè)接口函數(shù):
| extern "C" _declspec(dllexport) int Sum(int a,int b);//加法函數(shù)。 extern "C" _declspec(dllexport) int Max(int a, int b);//取較大值函數(shù) extern "C" _declspec(dllexport) int Min(int a, int b);//取較小值函數(shù) |
?
然后在“dllDemo.cpp”文件中實(shí)現(xiàn)三個(gè)接口函數(shù):
?
#include "dllDemo.h"extern "C" _declspec(dllexport)int Sum(int a, int b)
{
return a+b;
}
extern "C" _declspec(dllexport)int Max(int a, int b)
{
if(a>=b)return a;
else
return b;
}
extern "C" _declspec(dllexport)int Min(int a, int b)
{
if(a>=b)return b;
else
return a;
}
?
?
1.3 生成dll文件
編譯源文件,如果沒(méi)有出現(xiàn)錯(cuò)誤提示,那么,在項(xiàng)目文件根目錄的Debug文件夾內(nèi)會(huì)生成一個(gè)dll文件“dllDemo.dll”。
?
?
2 DLL調(diào)用
?
2.1 用C++調(diào)用顯式鏈接
新建一個(gè)Win32的控制臺(tái)程序進(jìn)行顯式調(diào)用:
1. 新建“dllConsoleEvident”的Win32控制臺(tái)程序項(xiàng)目
2. 新建cpp文件“dllConsoleEvident.cpp”
3. 將在第一節(jié)中,在Debug目錄下編譯生成的“dllDemo.dll”(顯式調(diào)用時(shí)只需要這一個(gè)文件就夠了)文件復(fù)制到“dllConsoleEvident”項(xiàng)目下的Debug文件夾根目錄下
4. 在“dllConsoleEvident.cpp”文件中編寫(xiě)以下代碼對(duì)dll中的函數(shù)進(jìn)行顯式調(diào)用
?
代碼 ////動(dòng)態(tài)加載DLL文件
#include <iostream.h>
#include<windows.h>
void main(void)
{
typedef int(*pMax)(int a,int b);//函數(shù)指針
typedef int(*pMin)(int a,int b);
pMax Max=NULL;
pMin Min=NULL;
HINSTANCE hDLL;
hDLL=LoadLibrary("MyDll.dll");//加載動(dòng)態(tài)鏈接庫(kù)MyDll.dll文件;
Max=(pMax)GetProcAddress(hDLL,"Max");
Min=(pMin)GetProcAddress(hDLL,"Min");
if (Max)//如果取出函數(shù)成功,則執(zhí)行下面的語(yǔ)句
{
int A=Max(5,8);
cout<<"比較的結(jié)果為"<<A;
}
if (Min)
{
int B=Min(5,8);
cout<<"比較的結(jié)果為"<<B;
}
FreeLibrary(hDLL);//卸載MyDll.dll文件;
}
?
?
?
2.2 用C++隱式鏈接(Win32控制臺(tái)程序)
新建一個(gè)Win32控制臺(tái)程序演示靜態(tài)調(diào)用
1. 利用向?qū)陆ā癲llConsoleStaticDemo”的空工程
2. 將“dllDemo.dll”和“dllDemo.lib”文件復(fù)制到Debug目錄下,并在項(xiàng)目中包含“dllDemo.lib”文件(或者),否則會(huì)出現(xiàn)dll函數(shù)找不到的連接錯(cuò)誤
3. 新建“dllConsoleStaticDemo.cpp”文件,并寫(xiě)入如下代碼:
?
extern "C"_declspec(dllimport) int Sum(int a,int b);extern "C"_declspec(dllimport) int Max(int a,int b);
extern "C"_declspec(dllimport) int Min(int a,int b);
#include <iostream.h>
void main()
{
int c=Sum(4,5);
c=Max(5,6);
c=Min(5,6);
cout<<"Hello,dllConsoleTest~!";
}
?
?
?
?
4.通過(guò)斷點(diǎn),可以看到dll函數(shù)調(diào)用成功
這種方式的靜態(tài)調(diào)用的特點(diǎn)是:在程序一開(kāi)始執(zhí)行的時(shí)候,就將dll文件全部加載到程序中,不會(huì)釋放。
?
2.3 用C++隱式鏈接(MFC窗口程序)
新建一個(gè)MFC基本對(duì)話(huà)框窗口程序進(jìn)行調(diào)用:
1. 利用向?qū)Ы⒁粋€(gè)MFC基本對(duì)話(huà)框
2. 將“dllDemo.dll”和”dllDemo.lib”文件復(fù)制到本項(xiàng)目的Debug目錄下,在VC工作空間的文件視圖下面將”dllDemo.lib”添加到項(xiàng)目中
3. 在“dllMfcDemoDlg.h”頭文件中的前面對(duì)來(lái)自外部的dll函數(shù)進(jìn)行聲明
?
// dllMfcDemoDlg.h : header file//
#if !defined(AFX_DLLMFCDEMODLG_H__E358B876_D188_48FD_8D83_794309C885A9__INCLUDED_)
#define AFX_DLLMFCDEMODLG_H__E358B876_D188_48FD_8D83_794309C885A9__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/////
// CDllMfcDemoDlg dialog
extern "C"_declspec(dllimport) int Sum(int a,int b);
extern "C"_declspec(dllimport) int Max(int a,int b);
extern "C"_declspec(dllimport) int Min(int a,int b);
……
?
?
?
?
4.在窗體界面上,雙擊“確定”按鈕,進(jìn)入到OnOk()的事件響應(yīng)函數(shù)體,編寫(xiě)調(diào)用代碼:
?
void CDllMfcDemoDlg::OnOK(){
// TODO: Add extra validation here
int c=Sum(4,5);
c=Max(5,6);
c=Min(5,6);
CDialog::OnOK();
}
?
?
?
通過(guò)設(shè)置斷點(diǎn)單步運(yùn)行就可以看到dll文件中的函數(shù)已經(jīng)被成功調(diào)用了。
?
2.4 用C#跨語(yǔ)言調(diào)用
C#控制臺(tái)程序調(diào)用VC++建立一個(gè)dll:
1. 用Visual Studio建立一個(gè)控制臺(tái)程序
2. 將“dllDemo.dll”文件復(fù)制到項(xiàng)目的Debug目錄下面
3. 在“Program.cs”中編寫(xiě)如下代碼
?
代碼 using System;using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;//引入dll文件中的函數(shù)
namespace ConsoleDllDemo
{
class Program
{
//引入dll文件中的函數(shù)
[DllImport("dllDemo.dll")]
private static extern int Sum(int a, int b);
[DllImport("dllDemo.dll")]
private static extern int Max(int a, int b);
[DllImport("dllDemo.dll")]
private static extern int Min(int a, int b);
static void Main(string[] args)
{
int a = Sum(3, 5);
Console.WriteLine(a);
Console.WriteLine(Max(5,10));
Console.WriteLine(Min(12,25));
Console.ReadKey();//要按鍵才退出。
}
}
}
?
?
?
然后斷點(diǎn)單步運(yùn)行,便可以看到調(diào)用函數(shù)的結(jié)果了。
關(guān)于DLL的調(diào)用的更詳細(xì)內(nèi)容可以參考另外一些文章:
http://dev.firnow.com/course/3_program/c++/cppsl/2008127/97781.html
http://dev.yesky.com/283/2640283_2.shtml
?
3?dll調(diào)試方法
在建立了dll項(xiàng)目后,并寫(xiě)好相應(yīng)的實(shí)現(xiàn)代碼,點(diǎn)擊“運(yùn)行”,會(huì)彈出現(xiàn)在的對(duì)話(huà)框:
然后瀏覽,找到一個(gè)調(diào)用了此dll文件的執(zhí)行文件“*.exe”文件,然后就可以對(duì)dll文件進(jìn)行斷點(diǎn)調(diào)試了。
這個(gè)“*.exe”文件可以是任何平臺(tái)的,C++也可以,C也可以,C#也可以,只要這個(gè)執(zhí)行文件調(diào)用了dll文件中的函數(shù)即可。
如果想更換調(diào)試的“*.exe”文件,可以在“工程-》設(shè)置”對(duì)話(huà)框中的“調(diào)試”選項(xiàng)卡進(jìn)行設(shè)置,瀏覽找到用戶(hù)需要的“*.exe”文件
說(shuō)明:以VC++環(huán)境中調(diào)用此dll為例,運(yùn)行dllDemo項(xiàng)目,然后會(huì)調(diào)用“*.exe”文件,如果此exe文件含有源文件,而且剛好在源文件的Debug目錄下面,那么,可以同時(shí)在exe文件的源文件中設(shè)置斷點(diǎn),進(jìn)行dll和調(diào)用dll兩個(gè)程序的聯(lián)調(diào)。(好像跨語(yǔ)言調(diào)用的時(shí)候不能進(jìn)行聯(lián)調(diào),筆者只在C++互相調(diào)用的時(shí)候聯(lián)調(diào)成功過(guò),但C#調(diào)用的時(shí)候沒(méi)有聯(lián)調(diào)成功,這個(gè)問(wèn)題有待解決)
?
?
4. DLL返回?cái)?shù)據(jù)類(lèi)型探究
目前寫(xiě)的DLL函數(shù)反返回值還僅限于整形,還沒(méi)有嘗試其它特殊類(lèi)型的返回值。更豐富的返回值類(lèi)型,還要今后慢慢學(xué)習(xí)和研究。等回學(xué)校了再研究吧。請(qǐng)見(jiàn)后續(xù)文章吧。
?
?
附件:
VC_dll_Realse.rar中是VC編寫(xiě)DLL并引用DLL的相關(guān)源碼文件
CShapr_ConsoleDllDemo.rar中是VS2005編寫(xiě)的C#引用VC編寫(xiě)的DLL函數(shù)的相關(guān)源碼文件
http://files.cnblogs.com/beer/VC_dll_Realese.rar
http://files.cnblogs.com/beer/CSharp_ConsoleDllDemo.rar
------------------------------------------------------------------
? ? 本文轉(zhuǎn)自wenglabs博客園博客,原文鏈接:http://www.cnblogs.com/greatverve/archive/2010/11/19/vc-dll.html,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
總結(jié)
- 上一篇: 模拟产品展示 Flash无法展示的追踪过
- 下一篇: auto与迭代器的用法_C++ STL