VC DLL學習

1 用VC創建DLL動態鏈接庫
1.1 創建dll項目

1.2 為dll項目編寫源文件

頭文件dllDemo.h
extern?"C"?_declspec(dllexport)?int?Sum(int?a,int?b);//加法函數。
extern?"C"?_declspec(dllexport)?int?Max(int?a,?int?b);//取較大值函數
extern?"C"?_declspec(dllexport)?int?Min(int?a,?int?b);//取較小值函數
源文件dllDemo.cpp
復制代碼
ExpandedBlockStart.gif大氣象
#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文件

編譯源文件,如果沒有出現錯誤提示,那么,在項目文件根目錄的Debug文件夾內會生成一個dll文件“dllDemo.dll”。

調用
新建了個MFC單對話框項目,
dllDemo.dll”和”dllDemo.lib”文件復制到本項目的Debug目錄下,
在VC工作空間的文件視圖下面將”dllDemo.lib”添加到項目中

在對話框頭文件添加引用:

復制代碼
ExpandedBlockStart.gif大氣象
//?FileOperDlg.h?:?頭文件
//

#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?對話框
class?CFileOperDlg?:?public?CDialog
{
//?構造
public:
????CFileOperDlg(CWnd
*?pParent?=?NULL);????//?標準構造函數

//?對話框數據
????enum?{?IDD?=?IDD_FILEOPER_DIALOG?};

????
protected:
????
virtual?void?DoDataExchange(CDataExchange*?pDX);????//?DDX/DDV?支持


//?實現
protected:
????HICON?m_hIcon;

????
//?生成的消息映射函數
????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;
};
復制代碼

?

調用:

復制代碼
CString?str;
int?c=Sum(4,5);??
//c=Max(5,6);??
//c=Min(5,6);
str.Format("%d",c);
AfxMessageBox(str);
復制代碼

?

調試
直接運行,選擇一個調用dll的exe確定之后,就可以調試了,設置個斷點試試。

?

?

?

參考:

VC++的DLL應用(含Demo演示)

作者:一點一滴的Beer?http://beer.cnblogs.com/

????? 在大學大一的時候學的是C,然后后來大二的時候專業又開了C++這個課程,然后再后來自己又自學了一點VC++,大三的時候也試著編寫過一個MFC的最簡單的窗口程序。到大四的時候,自己又做了一個GIS的項目,是用C#.NET來編寫的,然后發現C#上手好容易,而且還大部分語法規則都沿用了C,C++的習慣,于是覺得C++實在是沒有一點優勢可言啊。但這個暑假的實習經歷又改變了我的觀點:C++在寫窗口程序雖然麻煩,但是卻什么能做,而且對比C#來說,對運行環境的要求不高,不用像C#程序在安裝之前還要安裝100M多的運行.NET環境。C++和C#各有優缺,目前我對它們倆的定位是:C++用來寫一些底層的程序,比如驅動,或者是一些算法類型的函數接口,然后用C#來調用這些接口并進行界面設計。如何函數的實現跨語言呢?顯然DLL是個很重要的內容,故在此對VC++的DLL模塊進行介紹。

1?用VC創建DLL動態連接庫

?

1.1 創建dll項目

clip_image002

然后選擇“一個空的dll工程”,然后點擊“確定”便完成了“創建dll項目”的流程。

?

1.2 為dll項目編寫源文件

新建兩個文件:dllDemo.h, dllDemo.cpp

在頭文件”dllDemo.h”中聲明三個接口函數:

extern "C" _declspec(dllexport) int Sum(int a,int b);//加法函數。
extern "C" _declspec(dllexport) int Max(int a, int b);//取較大值函數
extern "C" _declspec(dllexport) int Min(int a, int b);//取較小值函數

?

然后在“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文件

編譯源文件,如果沒有出現錯誤提示,那么,在項目文件根目錄的Debug文件夾內會生成一個dll文件“dllDemo.dll”。

?

?

2 DLL調用

?

2.1 用C++調用顯式鏈接

clip_image004

新建一個Win32的控制臺程序進行顯式調用:

1. 新建“dllConsoleEvident”的Win32控制臺程序項目

2. 新建cpp文件“dllConsoleEvident.cpp”

3. 將在第一節中,在Debug目錄下編譯生成的“dllDemo.dll”(顯式調用時只需要這一個文件就夠了)文件復制到“dllConsoleEvident”項目下的Debug文件夾根目錄下

4. 在“dllConsoleEvident.cpp”文件中編寫以下代碼對dll中的函數進行顯式調用

?

復制代碼
代碼
 
//
//動態加載DLL文件
#include <iostream.h>
#include
<windows.h>
void main(void)
{
typedef
int(*pMax)(int a,int b);//函數指針
typedef int(*pMin)(int a,int b);
pMax Max
=NULL;
pMin Min
=NULL;
HINSTANCE hDLL;
hDLL
=LoadLibrary("MyDll.dll");//加載動態鏈接庫MyDll.dll文件;
Max=(pMax)GetProcAddress(hDLL,"Max");
Min
=(pMin)GetProcAddress(hDLL,"Min");
if (Max)//如果取出函數成功,則執行下面的語句
{
int A=Max(5,8);
cout
<<"比較的結果為"<<A;
}
if (Min)
{
int B=Min(5,8);
cout
<<"比較的結果為"<<B;
}
FreeLibrary(hDLL);
//卸載MyDll.dll文件;
}
復制代碼

?

?

?

2.2 用C++隱式鏈接(Win32控制臺程序)

clip_image006

新建一個Win32控制臺程序演示靜態調用

1. 利用向導新建“dllConsoleStaticDemo”的空工程

2. 將dllDemo.dll”和“dllDemo.lib文件復制到Debug目錄下,并在項目中包含“dllDemo.lib”文件(或者),否則會出現dll函數找不到的連接錯誤

3. 新建“dllConsoleStaticDemo.cpp”文件,并寫入如下代碼:

?

復制代碼
 
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.通過斷點,可以看到dll函數調用成功

這種方式的靜態調用的特點是:在程序一開始執行的時候,就將dll文件全部加載到程序中,不會釋放。

?

2.3 用C++隱式鏈接(MFC窗口程序)

clip_image008

新建一個MFC基本對話框窗口程序進行調用:

1. 利用向導建立一個MFC基本對話框

2. 將dllDemo.dll”和”dllDemo.lib”文件復制到本項目的Debug目錄下,在VC工作空間的文件視圖下面將”dllDemo.lib”添加到項目中

3. 在“dllMfcDemoDlg.h”頭文件中的前面對來自外部的dll函數進行聲明

?

復制代碼
 
// 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.在窗體界面上,雙擊“確定”按鈕,進入到OnOk()的事件響應函數體,編寫調用代碼:

?

復制代碼
 
void CDllMfcDemoDlg::OnOK()
{
// TODO: Add extra validation here
int c=Sum(4,5);
c
=Max(5,6);
c
=Min(5,6);
CDialog::OnOK();
}
復制代碼

?

?

?

通過設置斷點單步運行就可以看到dll文件中的函數已經被成功調用了。

?

2.4 用C#跨語言調用

C#控制臺程序調用VC++建立一個dll:

clip_image010

1. 用Visual Studio建立一個控制臺程序

2. 將“dllDemo.dll”文件復制到項目的Debug目錄下面

3. 在“Program.cs”中編寫如下代碼

?

復制代碼
代碼
 
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;//引入dll文件中的函數
namespace ConsoleDllDemo
{
class Program
{
//引入dll文件中的函數
[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();
//要按鍵才退出。
}
}
}
復制代碼

?

?

?

然后斷點單步運行,便可以看到調用函數的結果了。

關于DLL的調用的更詳細內容可以參考另外一些文章:

http://dev.firnow.com/course/3_program/c++/cppsl/2008127/97781.html

http://dev.yesky.com/283/2640283_2.shtml

?

3?dll調試方法

在建立了dll項目后,并寫好相應的實現代碼,點擊“運行”,會彈出現在的對話框:

clip_image012

然后瀏覽,找到一個調用了此dll文件的執行文件“*.exe”文件,然后就可以對dll文件進行斷點調試了。

這個“*.exe”文件可以是任何平臺的,C++也可以,C也可以,C#也可以,只要這個執行文件調用了dll文件中的函數即可。

如果想更換調試的“*.exe”文件,可以在“工程-》設置”對話框中的“調試”選項卡進行設置,瀏覽找到用戶需要的“*.exe”文件

clip_image014

說明:以VC++環境中調用此dll為例,運行dllDemo項目,然后會調用“*.exe”文件,如果此exe文件含有源文件,而且剛好在源文件的Debug目錄下面,那么,可以同時在exe文件的源文件中設置斷點,進行dll和調用dll兩個程序的聯調。(好像跨語言調用的時候不能進行聯調,筆者只在C++互相調用的時候聯調成功過,但C#調用的時候沒有聯調成功,這個問題有待解決)

?

?

4. DLL返回數據類型探究

目前寫的DLL函數反返回值還僅限于整形,還沒有嘗試其它特殊類型的返回值。更豐富的返回值類型,還要今后慢慢學習和研究。等回學校了再研究吧。請見后續文章吧。

?

?

附件:

VC_dll_Realse.rar中是VC編寫DLL并引用DLL的相關源碼文件

CShapr_ConsoleDllDemo.rar中是VS2005編寫的C#引用VC編寫的DLL函數的相關源碼文件

http://files.cnblogs.com/beer/VC_dll_Realese.rar

http://files.cnblogs.com/beer/CSharp_ConsoleDllDemo.rar

------------------------------------------------------------------



? ? 本文轉自wenglabs博客園博客,原文鏈接:http://www.cnblogs.com/greatverve/archive/2010/11/19/vc-dll.html,如需轉載請自行聯系原作者



本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/454267.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/454267.shtml
英文地址,請注明出處:http://en.pswp.cn/news/454267.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mciSendString 多線程播放多首音樂 注意事項

昨天晚上遇到一個問題&#xff1a; 使用 mciSendString 控制播放多首音樂的時候&#xff0c;出現最后一次播放的音樂無法通過 mciSendString ("close mp3") 關閉音樂的播放。 mciSendString 在多個線程中調用。 到23點&#xff0c;問題依然沒解決&#xff0c;只好先…

python代碼比例_Python如何輸出百分比

Python 輸出百分比的兩種方式 注&#xff1a; 在python3環境下測試。 方式1&#xff1a;直接使用參數格式化&#xff1a;{:.2%} {:.2%}&#xff1a; 顯示小數點后2位 顯示小數點后2位&#xff1a; >>> print(percent: {:.2%}.format(42/50)) percent: 84.00% 不顯示小…

為機器學習占地15

是將若干個學習器(分類器&回歸器)組合之后產生一個新學習器。弱分類器(weak learner)指那些分類準確率只稍微好于隨機猜測的分類器(errorrat弱分類器的多樣性(Diversity)。而且集成不穩定的算法也能夠得到一個比較明顯的性能提升。 常見的集成學習思想有&#xff1a;Baggi…

編寫一個項目開發文檔

項目開發過程中為了增加程序的可讀性和程序的健壯性&#xff0c; 方便后期程序的調試和維護&#xff0c;所以需要在開發過程中統一技術規范&#xff0c;一般會在項目初期確定好相關文檔作為這一統一的規范。不同公司會對文檔做不同要求&#xff0c;劃不同的分類&#xff0c;但一…

樂在其中設計模式(C#) - 原型模式(Prototype Pattern)

[索引頁][源碼下載]樂在其中設計模式(C#) - 原型模式(Prototype Pattern)作者&#xff1a;webabcd介紹用原型實例指定創建對象的種類&#xff0c;并且通過拷貝這個原型來創建新的對象。示例有一個Message實體類&#xff0c;現在要克隆它。MessageModelusing System; using Syst…

python123添加列表元素_Python之列表

Python變量沒有數據類型&#xff0c;所以Python沒有數組。 整數&#xff1b;浮點數&#xff1b;字符串&#xff1b;對象 創建一個列表&#xff1a; 1.member[大魚,123,3.14,[1,2,3]] 2.empty[] 向列表添加元素&#xff1a; append&#xff08;&#xff09;&#xff1a; member[…

為機器學習占地14

是將若干個學習器(分類器&回歸器)組合之后產生一個新學習器。弱分類器(weak learner)指那些分類準確率只稍微好于隨機猜測的分類器(errorrate <。 集成算法的成功在于保證弱分類器的多樣性(Diversity)。而且集成不穩定的算法也能夠得到一個比較明顯的性能提升。 常見的…

優秀程序員 分析提高能力 程序進階

我出生在南方的一個農村。還記得小時候家里是很窮的&#xff0c;那時候上學也很便宜&#xff0c;我已記不清初中以前的學費是多少了。反正從小在家里玩泥巴&#xff0c;有一日村里兩個女孩去上學&#xff0c;看到我就說一起去上學吧。當時一想&#xff0c;玩泥巴也厭煩了&#…

html中通過點擊button標簽實現頁面跳轉的三種方法

方法1&#xff1a;使用onclick事件 <input type"button" value"按鈕"onclick"javascrtpt:window.location.hrefhttp://www.baidu.com/" />或者直接使用button標簽 <button onclick"window.location.href https://www.baidu.com…

mybatis調用存儲過程

直接貼代碼吧 注解式可以調用 但是不能返回結果 所有我就貼配置式的 有知道注解怎么返回結果的請評論 數據庫代碼 #表 DROP TABLE IF EXISTS p_user; CREATE TABLE p_user (id int(11) NOT NULL AUTO_INCREMENT,name varchar(10) DEFAULT NULL,sex char(2) DEFAULT NULL,PRIMAR…

java dump分析工具_Java 性能分析工具 (2):Java 內置監控工具

引言本文為 Java 性能分析工具系列文章第二篇&#xff0c;第一篇&#xff1a;操作系統工具。在本文中將介紹如何使用 Java 內置監控工具更加深入的了解 Java 應用程序和 JVM 本身。在 JDK 中有許多內置的工具&#xff0c;其中包括&#xff1a;jcmd&#xff1a;打印一個 Java 進…

Linux+php+memcache+APC加速PHP網站

一、前言對于一個站長而言不僅要做好網站內容外&#xff0c;還需要對網站做優化&#xff0c;如果速度訪問很慢的&#xff0c;沒有人下次再訪問你的站點&#xff0c;目前國內使用php的網站不計其數&#xff0c;這里用我的博客為例&#xff1a;http://chinaapp.sinaapp.com 以加速…

為機器學習占地13

是將若干個學習習 弱分類器間存在一定的差異性&#xff0c;這會導致分類的邊界不同&#xff0c;也就是說可能存在錯誤。那么將多個弱分類器合并后&#xff0c;就可以得到更加合理的邊界&#xff0c;減少整體的錯誤率&#xff0c;實現更好的效果&#xff1b; 對于數據集過大或者…

Python面試題(第二篇)

第二部分 網絡編程和并發&#xff08;34題&#xff09;1、簡述 OSI 七層協議。2、什么是C/S和B/S架構&#xff1f;3、簡述 三次握手、四次揮手的流程。4、什么是arp協議&#xff1f;5、TCP和UDP的區別&#xff1f;6、什么是局域網和廣域網&#xff1f;7、為何基于tcp協議的通信…

noip模擬賽 radius

分析&#xff1a;這道題實在是不好想&#xff0c;一個可以騙分的想法是假定要求的那個點在中心點上,可以騙得不少分.但是在邊上的點要怎么確定呢&#xff1f;理論復雜度O(&#xfe62;無窮).答案一定是和端點有關的&#xff0c;涉及到最大值最小&#xff0c;考慮二分最大值&…

來自IT公司速查手冊的各大IT公司薪資和待遇內幕

來自IT公司速查手冊的各大IT公司薪資和待遇內幕 &#xff08;轉載于 http://xuchaoyi99.cnblogs.com/ &#xff09; 編號 1. 杭州 諾基亞 2. 南京 趨勢科技 Trend 3. 北京 聯想&#xff08;北京&#xff09;有限公司 4. 深圳 華為 5. 深圳 中興通訊 6. 上海 SAP 7.…

Docker 精通之 Dockerfile

Docker 精通系列 Docker 精通之入門Docker 精通之微服務Docker 精通之常用命令Docker 精通之 Dockerfile 1.基本說明 Dockfile 是一個用于編寫 docker 鏡像生成過程的文件&#xff0c;其有特定的語法。在一個文件夾中&#xff0c;如果有一個名字為 Dockfile 的文件&#xff0c…

c語言中int的取值范圍_c語言入門(1)

c語言入門C語言一經出現就以其功能豐富、表達能力強、靈活方便、應用面廣等特點迅速在全世界普及和推廣。C語言不但執行效率高而且可移植性好&#xff0c;可以用來開發應用軟件、驅動、操作系統等。C語言也是其它眾多高級語言的鼻祖語言&#xff0c;所以說學習C語言是進入編程世…

vue : 無法將“vue”項識別為 cmdlet、函數、腳本文件或可運行程序的名稱。請檢查名稱的拼寫,如果包括路徑,請確保路徑正確, 然后再試一次。

vue : 無法將“vue”項識別為 cmdlet、函數、腳本文件或可運行程序的名稱。請檢查名稱的拼寫&#xff0c;如果包括路徑&#xff0c;請確保路徑正確&#xff0c; 然后再試一次。 報錯原因&#xff1a; 沒有安裝腳手架vue-cli 解決方法&#xff1a;安裝腳手架vue-cli npm inst…

session的生命周期

session的生命周期分為創建、活動、銷毀三個階段 創建一個新的會話不代表舊的會話就銷毀了 session.invalidate()方法可以銷毀當前會話 在page1中寫上這個方法再打開網頁 說明該會話被銷毀了出現了錯誤 我們把這個方法寫在所有代碼段的下面 再打開這個網頁 刷新網頁 這個sessio…