使用extern C改善顯式調用dll

extern "C"的簡單解析??????? ?我們前面介紹了顯式調用dll的方法,例如


http://www.cnblogs.com/laogao/archive/2012/12/07/2806528.html?,其中在GetProcAddress第二個參數的填寫煞費苦心,我們需要比較麻煩地使用vs自帶的dumpbin查看dll的具體函數,即使后來可以使用MAKEINTRESOURCE直接填寫函數序號來不直接填寫函數名,依然你需要在dumpbin中查找函數的序號,比較費力。

???????? 其實我們有更好的方法來解決這個問題,其中一個比較好的一個方法是改用extern "C"來修飾函數,使之按照c的風格來編譯函數。我們知道c不支持函數重載,因此我們定義的時候用的什么名字,在顯式調用dll的時候也是用的這個名字,完全不用改變,很簡單。

??????? 在進行下面的介紹之前,先可以閱讀這個文章《extern "C"的簡單解析》

??????? 下面我們介紹兩個例子。

例1.?在純C++環境下使用c語言方式編譯dll,然后調用

??????CreateDLL.h

<span style="color:#000000;">// 下列 ifdef 塊是創建使從 DLL 導出更簡單的
// 宏的標準方法。此 DLL 中的所有文件都是用命令行上定義的 CREATEDLL_EXPORTS
// 符號編譯的。在使用此 DLL 的
// 任何其他項目上不應定義此符號。這樣,源文件中包含此文件的任何其他項目都會將
// CREATEDLL_API 函數視為是從 DLL 導入的,而此 DLL 則將用此宏定義的
// 符號視為是被導出的。
#ifdef CREATEDLL_EXPORTS
#define CREATEDLL_API __declspec(dllexport)
#else
#define CREATEDLL_API __declspec(dllimport)
#endif#ifdef __cplusplus
extern "C"
{
#endifCREATEDLL_API void printMax(int&, int&);
#ifdef __cplusplus
}
#endif // __cplusplus
</span>
// CreateDLL.cpp : 定義 DLL 應用程序的導出函數。
//#include "stdafx.h"
#include "CreateDLL.h"
#include <iostream>CREATEDLL_API void printMax(int& a, int& b)
{std::cout << "Among (" << a << "," << b << "), the Max Number is " << (a > b ? a : b) << "\n";
}

然后點擊“生成”,即可生成dll和lib。接下來我們就可以直接使用了。注意:生成dll的時候,需要先設置dll的項目為啟動項。當使用dll的時候,需設置使用dll的項目為啟動項。

先看顯式調用:

#include <Windows.h>
#include <iostream>typedef void(*FUNA)(int&, int&);int main()
{const char* dllName = "CreateDLL.dll";int x(100), y(100);HMODULE hDLL = LoadLibrary(dllName);if (hDLL!=NULL){FUNA fp1 = FUNA(GetProcAddress(hDLL, "printMax"));if (fp1!=NULL){std::cout << "Input 2 Numbers:";std::cin >> x >> y;fp1(x, y);}else{std::cout << "connot find the function "<<"printMax" << std::endl;}FreeLibrary(hDLL);}else{std::cout << "cannot load dll"<<dllName << std::endl;}system("pause");return 0;}

注意觀察,我們的GetProcAddress的第二個參數直接使用原來的函數名。另外需要注意的是在使用dll的項目中,我們沒有包含dll的頭文件,但是仍然可以使用。但是有時候也過不去,此時你需要包含dll的.h的路徑。

再看隱式調用

#include "CreateDLL.h"
#include <iostream>
using namespace std;#pragma  comment(lib,"CreateDLL.lib")int main()
{int a,b;cout << "input 2 num:";cin >> a >> b;printMax(a,b);system("pause");return 0;
}

將.h,.lib,.dll一塊兒放在項目目錄下,然后在程序中使用#pragma comment(lib,"CreateDLL.lib"),即可成功鏈接dll。與顯式調用,隱式調用比較簡單。

另外在上一篇《c++顯式加載dll并使用DLL的類》 ,我們也使用了extern "C"的風格

extern "C" INTERFACE_API Interface* Export(void); 

例2.?在純C環境下使用c語言方式編譯dll,然后在C++中調用
????
CreateDLL.h

//c.h
#ifndef _C_H_
#define _C_H_   //防止被重復包含#ifdef CREATEDLL_EXPORTS
#define CREATEDLL_API __declspec(dllexport)
#else
#define  CREATEDLL_API __declspec(dllimport)
#endif#ifdef __cplusplus
extern "C" {
#endifextern  CREATEDLL_API int add(int x, int y);#ifdef __cplusplus
}
#endif#endif

CreateDLL.c

#include "CreateDLL.h"
int add(int x, int y)
{return x + y;
}

然后我們就可以生成dll了。注意我們這里都是c語言。

然后我們在c++中調用dll。

顯式調用:

#include <Windows.h>
#include <iostream>
#include "CreateDLL.h"typedef int(*Func)(int, int);#pragma  comment(lib,"CreateDLL.lib")int main()
{HMODULE Hdll = LoadLibrary("CreateDLL.dll");if (Hdll!=nullptr){Func f = Func(GetProcAddress(Hdll, "add"));if (f!=nullptr){std::cout << "input 2 num:";int a, b;std::cin >> a >> b;std::cout << "result is " << add(a, b);}else{std::cout << "connot find the function " << "add" << std::endl;}FreeLibrary(Hdll);}else{std::cout << "cannot load dll" << "CreateDLL.dll" << std::endl;}system("pause");return 0;
}

注意要將CreateDLL.h和CreateDLL.lib放在項目目錄下。

隱式調用:

#include "CreateDLL.h"
#include <iostream>
using namespace std;#pragma  comment(lib,"CreateDLL.lib")int main()
{int a,b;cout << "input 2 num:";cin >> a >> b;cout<<"result is "<<add(a,b);system("pause");return 0;
}

解讀:

文件為*.c,__cplusplus沒有被定義,extern "C" {}這時沒有生效,對于C語言只是extern int add(int, int);而編譯c++源文件,__cplusplus被定義,對于C++他看到的是extern "C" {extern int add(int, int);},編譯器就會知道add(1, 0)調用的是C連接。?
很多DLL的生成文件(XXX.c)中常出現extern "C" ,windows采用C語言編譯創建dll,C程序可以正確調用DLL,而當用戶使用C++調用DLL時,extern "C" {}就起作用了。

附錄:

1.例1

2.例2




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

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

相關文章

《移動App測試的22條軍規》—App測試綜合案例分析23.13節測試微信App的流量和電量消耗...

本節書摘來自異步社區《移動App測試的22條軍規》一書中的App測試綜合案例分析&#xff0c;第23.13節測試微信App的流量和電量消耗&#xff0c;作者黃勇&#xff0c;更多章節內容可以訪問云棲社區“異步社區”公眾號查看。 23.13 測試微信App的流量和電量消耗關于微信App消耗流…

UVA 10269 Super Mario,最短路+動態規劃

這個題目我昨晚看到的&#xff0c;沒什么思路&#xff0c;因為馬里奧有boot加速器&#xff0c;只要中間沒有城堡&#xff0c;即可不耗時間和腳力&#xff0c;瞬間移動不超過L距離&#xff0c;遇見城堡就要停下來&#xff0c;當然不能該使用超過K次。。。我糾結了很久&#xff0…

python做數據可視化的代碼_Python數據可視化正態分布簡單分析及實現代碼

Python說來簡單也簡單&#xff0c;但是也不簡單&#xff0c;尤其是再跟高數結合起來的時候。。。 正態分布&#xff08;Normaldistribution&#xff09;&#xff0c;也稱“常態分布”&#xff0c;又名高斯分布&#xff08;Gaussiandistribution&#xff09;&#xff0c;最早由A…

ACdream 1061(abs用法)

題目鏈接&#xff1a;http://acdream.info/problem?pid1061 主要是abs用法&#xff0c;看題目的數據 long long的最大值&#xff1a;9223372036854775807 long long的最小值&#xff1a;-9223372036854775808 unsigned long long的最大值&#xff1a;18446744073709551615 由題…

wpf window 不執行show 就不能load執行_Numpy反序列化命令執行漏洞分析(CVE-2019-6446)附0day...

1、介紹 NumPy 是 Python 機器學習庫中之一&#xff0c;主要對于多為數組執行計算。NumPy 提供大量的 函數和操作&#xff0c;能夠幫助程序員便利進行數值計算。在 NumPy 1.16.0 版本之前存在反序列化 命令執行漏洞&#xff0c;用戶加載惡意的數據源造成命令執行。2、環境 軟件…

使用Def文件導出dll

前面我們介紹了dll的生成&#xff0c;大多數是使用extern "C"__declspec(dllexport)函數名的方法導出dll。其實我們還有另一種方法來導出dll。 先介紹參考文獻&#xff1a; 1.dll導出聲明相關 2.VS2012中 C創建DLL圖解 3.DLL中導出函數的兩種方式(dllexport與.…

HDU 1003 Maxsum

題目大意&#xff1a;求出數列的最大子段和&#xff0c;并且說明是從第幾項至第幾項。 題解1&#xff1a;簡單貪心。 #include <cstdio> #define rep(i,n) for(int i1;i<n;i) int main(){int t,l0;scanf("%d",&t);while(t--&&l){if(l!1)printf…

《JavaScript面向對象精要》——1.8 原始封裝類型

本節書摘來自異步社區《JavaScript面向對象精要》一書中的第1章&#xff0c;第1.8節&#xff0c;作者&#xff1a;【美】Nicholas C. Zakas著&#xff0c;更多章節內容可以訪問云棲社區“異步社區”公眾號查看 1.8 原始封裝類型 JavaScript中一個最讓人困惑的部分可能就是原始…

XML語法學習

本文章集合兩篇博文而寫&#xff0c;兩篇博文地址&#xff1a; XML學習總結(二)——XML入門&#xff1a; XML基礎<第一篇> XML簡介 XML是一種標記語言&#xff0c;用于描述數據&#xff0c;它提供一種標準化的方式來來表示文本數據。XML文檔以.xml為后綴。需要徹底注…

FM實現F4幫助系列三:彈出框多篩選…

FM實現F4幫助系列三&#xff1a;彈出框多篩選條件的搜索幫助&#xff08;根據搜索幫助篩選字段&#xff09;函數&#xff1a;F4IF_GET_SHLP_DESCRF4IF_START_VALUE_REQUEST效果圖&#xff1a;本例子代碼&#xff1a;找到需要的幫助:*&------------------------------------…

[數分提高]2014-2015-2第9教學周第1次課 (2015-04-28)

設 $$\bex a,b>0,\quad 0\leq f\in \calR[a,b],\quad \int_a^b xf(x)\rd x0. \eex$$ 試證: $$\bex \int_a^b x^2f(x)\rd x\leq ab \int_a^b f(x)\rd x; \eex$$ 并給出使得下列不等式成立的 (您認為的) 最優數: $$\bex \int_a^b x^3f(x)\rd x\leq (\quad) \int_a^b f(x)\rd x…

《計算復雜性:現代方法》——0.2 判定問題/語言

本節書摘來自華章計算機《計算復雜性&#xff1a;現代方法》一書中的第0章&#xff0c;第0.2節&#xff0c;作者 &#xff3b;美&#xff3d;桑杰夫阿羅拉&#xff08;Sanjeev Arora&#xff09;&#xff0c;博阿茲巴拉克&#xff08;Boaz Barak&#xff09;&#xff0c;譯 駱吉…

python從date目錄導入數據集_使用python劃分數據集

無論是訓練機器學習或是深度學習&#xff0c;第一步當然是先劃分數據集啦&#xff0c;今天小白整理了一些劃分數據集的方法&#xff0c;希望大佬們多多指教啊&#xff0c;嘻嘻~ 首先看一下數據集的樣子&#xff0c;flower_data文件夾下有四個文件夾&#xff0c;每個文件夾表示一…

開源牛人 zcbenz

事情是這樣的&#xff0c;微軟推出了Visual Studio Code&#xff0c;我很好奇他怎么做跨平臺的&#xff0c;所以就找找資料&#xff0c;在他的網站中是這么描述的&#xff1a; Architecturally, Visual Studio Code combines the best of web, native, and language-specific t…

eclipse 與 tomcat 的那些路徑

我們用mvn創建了一個web工程&#xff0c;同時希望在eclipse里調試開發。mvn有mvn的路徑要求&#xff0c;eclispe有eclipse的默認路徑&#xff0c;怎么整合二者&#xff1f; 首先介紹一下eclipse的默認路徑。 重點在Server Locations里面。 下面我們把[workspace]/.metadata\.pl…

boost解析xml文件

前面我們介紹了xml文件&#xff0c;今天我們試著用boost庫來解析xml文件。我們將舉兩個例子來說明怎么使用。 來自boost官方的例子 先看xml文件的內容&#xff1a; <debug><filename>debug.log</filename><modules><module>Finance</modul…

使用網橋模式(bridge networking mode)配置KVM-QUME虛擬機網絡

&#xff08;1&#xff09;linux要工作在網橋模式&#xff0c;所以必須安裝兩個RPM包。即&#xff1a;bridge-utils和tunctl。它們提供所需的brctl、tunctl命令行工具。能夠使用yum在線安裝&#xff1a; [rootserver3 ~]# yum install bridge-utils &#xff08;2&#xff09;查…

python數據處理常用函數_pandas數據分析常用函數總結大全:上篇

基礎知識在數據分析中就像是九陽神功&#xff0c;熟練的掌握&#xff0c;加以運用&#xff0c;就可以練就深厚的內力&#xff0c;成為絕頂高手自然不在話下&#xff01; 為了更好地學習數據分析&#xff0c;我對于數據分析中pandas這一模塊里面常用的函數進行了總結。整篇總結&…

XML的應用

1.XML的定義: XML 于 1998 年 2 月 10 日成為 W3C 的推薦標準。xml一般指可擴展標記語言&#xff0c;可擴展標記語言是一種很像超文本標記語言的標記語言。它的設計宗旨是傳輸數據&#xff0c;而不是顯示數據。 2.通過XML我們可以自定義自己的標簽&#xff0c;如&#xff1a; &…

虛擬機VMware里 windows server 2003 擴充C盤方法

你會經常用windows server 2003 嗎&#xff1f;應該不會吧&#xff0c;有時一些東西必須裝在windows server 2003 上才能用&#xff0c;所以 用虛擬機把&#xff0c;好&#xff0c;裝在虛擬機上&#xff0c;8G的C盤夠你用嗎&#xff0c;一個稍微大點的軟件就可能就沒空間來存儲…