VS2017中 C# dll引用(C生成dll铣揉,C++生成dll)小結(jié)

dll引用小結(jié)

一哪审、dll與應(yīng)用程序

動(dòng)態(tài)鏈接庫(kù)(也稱為DLL蛾魄,即為“Dynamic Link Library”的縮寫(xiě))是Microsoft Windows最重要的組成要素之一,打開(kāi)Windows系統(tǒng)文件夾湿滓,你會(huì)發(fā)現(xiàn)文件夾中有很多DLL文件滴须,Windows就是將一些主要的系統(tǒng)功能以DLL模塊的形式實(shí)現(xiàn)。
動(dòng)態(tài)鏈接庫(kù)是不能直接執(zhí)行的叽奥,也不能接收消息扔水,它只是一個(gè)獨(dú)立的文件,其中包含能被程序或其它DLL調(diào)用來(lái)完成一定操作的函數(shù)(方法朝氓。注:C#中一般稱為“方法”)魔市,但這些函數(shù)不是執(zhí)行程序本身的一部分,而是根據(jù)進(jìn)程的需要按需載入赵哲,此時(shí)才能發(fā)揮作用待德。
DLL只有在應(yīng)用程序需要時(shí)才被系統(tǒng)加載到進(jìn)程的虛擬空間中,成為調(diào)用進(jìn)程的一部分枫夺,此時(shí)該DLL也只能被該進(jìn)程的線程訪問(wèn)将宪,它的句柄可以被調(diào)用進(jìn)程所使用,而調(diào)用進(jìn)程的句柄也可以被該DLL所使用橡庞。在內(nèi)存中较坛,一個(gè)DLL只有一個(gè)實(shí)例,且它的編制與具體的編程語(yǔ)言和編譯器都沒(méi)有關(guān)系扒最,所以可以通過(guò)DLL來(lái)實(shí)現(xiàn)混合語(yǔ)言編程丑勤。DLL函數(shù)中的代碼所創(chuàng)建的任何對(duì)象(包括變量)都?xì)w調(diào)用它的線程或進(jìn)程所有。
下面列出了當(dāng)程序使用 DLL 時(shí)提供的一些優(yōu)點(diǎn):[1]

  1. 使用較少的資源
    當(dāng)多個(gè)程序使用同一個(gè)函數(shù)庫(kù)時(shí)吧趣,DLL 可以減少在磁盤(pán)和物理內(nèi)存中加載的代碼的重復(fù)量法竞。這不僅可以大大影響在前臺(tái)運(yùn)行的程序香缺,而且可以大大影響其他在 Windows 操作系統(tǒng)上運(yùn)行的程序廊宪。
  2. 推廣模塊式體系結(jié)構(gòu)
    DLL 有助于促進(jìn)模塊式程序的開(kāi)發(fā)股耽。這可以幫助您開(kāi)發(fā)要求提供多個(gè)語(yǔ)言版本的大型程序或要求具有模塊式體系結(jié)構(gòu)的程序泽示。模塊式程序的一個(gè)示例是具有多個(gè)可以在運(yùn)行時(shí)動(dòng)態(tài)加載的模塊的計(jì)帳程序。
  3. 簡(jiǎn)化部署和安裝
    當(dāng) DLL 中的函數(shù)需要更新或修復(fù)時(shí)秉剑,部署和安裝 DLL 不要求重新建立程序與該 DLL 的鏈接泛豪。此外,如果多個(gè)程序使用同一個(gè) DLL侦鹏,那么多個(gè)程序都將從該更新或修復(fù)中獲益诡曙。當(dāng)您使用定期更新或修復(fù)的第三方 DLL 時(shí),此問(wèn)題可能會(huì)更頻繁地出現(xiàn)略水。

二价卤、Dll的調(diào)用

每種編程語(yǔ)言調(diào)用DLL的方法都不盡相同,在此只對(duì)用C#調(diào)用DLL的方法進(jìn)行介紹渊涝。首先,您需要了解什么是托管,什么是非托管慎璧。一般可以認(rèn)為:非托管代碼主要是基于win 32平臺(tái)開(kāi)發(fā)的DLL,activeX的組件跨释,托管代碼是基于.net平臺(tái)開(kāi)發(fā)的胸私。如果您想深入了解托管與非托管的關(guān)系與區(qū)別,及它們的運(yùn)行機(jī)制鳖谈,請(qǐng)您自行查找資料岁疼,本文件在此不作討論。

調(diào)用DLL非托管函數(shù)的一般方法

首先缆娃,應(yīng)該在C#語(yǔ)言源程序中聲明外部方法捷绒,其基本形式是:
[DLLImport(“DLL文件”)]
修飾符 extern 返回變量類型 方法名稱 (參數(shù)列表)
其中:
DLL文件:包含定義外部方法的庫(kù)文件。
修飾符: 訪問(wèn)修飾符贯要,除了abstract以外在聲明方法時(shí)可以使用的修飾符暖侨。
返回變量類型:在DLL文件中你需調(diào)用方法的返回變量類型。
方法名稱:在DLL文件中你需調(diào)用方法的名稱郭毕。
參數(shù)列表:在DLL文件中你需調(diào)用方法的列表它碎。
注意:需要在程序聲明中使用System.Runtime.InteropServices命名空間。
DllImport只能放置在方法聲明上显押。
DLL文件必須位于程序當(dāng)前目錄或系統(tǒng)定義的查詢路徑中(即:系統(tǒng)環(huán)境變量中Path所設(shè)置的路徑)。
返回變量類型傻挂、方法名稱乘碑、參數(shù)列表一定要與DLL文件中的定義相一致。
若要使用其它函數(shù)名金拒,可以使用EntryPoint屬性設(shè)置兽肤,如:
[DllImport("user32.dll", EntryPoint="MessageBoxA")]
static extern int MsgBox(int hWnd, string msg, string caption, int type);
其它可選的 DllImportAttribute 屬性:
CharSet 指示用在入口點(diǎn)中的字符集套腹,如:CharSet=CharSet.Ansi;
SetLastError 指示方法是否保留 Win32"上一錯(cuò)誤"资铡,如:SetLastError=true电禀;
ExactSpelling 指示 EntryPoint 是否必須與指示的入口點(diǎn)的拼寫(xiě)完全匹配,如:ExactSpelling=false笤休;
PreserveSig指示方法的簽名應(yīng)當(dāng)被保留還是被轉(zhuǎn)換尖飞, 如:PreserveSig=true;
CallingConvention指示入口點(diǎn)的調(diào)用約定店雅, 如:CallingConvention=CallingConvention.Winapi政基;
C#例子:
1.啟動(dòng)VS.NET,新建一個(gè)項(xiàng)目闹啦,項(xiàng)目名稱為“import1”沮明,模板為“控制臺(tái)應(yīng)用程序”。
代碼如下

namespace import1
{
  class Program
  {
    [DllImport("user32.dll", EntryPoint = "MessageBoxA")]
    static extern int MsgBox(int hWnd, string msg, string caption, int type);
    static void Main(string[] args)
    {
        MsgBox(0, " 這就是用 DllImport 調(diào)用 DLL 彈出的提示框哦窍奋! ", " 挑戰(zhàn)杯 ", 0x30);
    }
  }
}

然后運(yùn)行即可
image.png

生成一個(gè)自定義的C語(yǔ)言dll

所用平臺(tái)VisualStudio 2017
新建C++空項(xiàng)目
右鍵項(xiàng)目--->屬性--->選擇配置類型為動(dòng)態(tài)庫(kù)


image.png

在頭文件和源文件下分別建立test.h和test.c
test.h

__declspec(dllexport) int sum(int a, int b);

test.c


//test.c
#include "test.h"
#include <stdio.h>

int sum(int a, int b) {
    return a + b;
}

生成項(xiàng)目荐健,在相應(yīng)的Debug文件夾下可以找到EasyHelloWorlddll.dll
找不到可以用listary搜索。
然后把該dll拷貝到C#項(xiàng)目文件的exe文件夾內(nèi)(點(diǎn)擊生成之后的Debug或者release文件夾)琳袄。

C# Vs中使用C的Dll

新建C#控制臺(tái)程序ConsoleAppTestDllImport
Program.cs代碼如下

using System;

namespace ConsoleAppTestDllImport
{
    using System.Runtime.InteropServices;

    class Program
    {
        [DllImport("EasyHelloWorlddll", EntryPoint = "sum", CallingConvention = CallingConvention.Cdecl)]
        public static extern int Sum(int a, int b);

        static void Main(string[] args)
        {

            Console.WriteLine(Sum(2,3));
            Console.ReadKey();
        }
}

其中 EntryPoint="sum"是定義入口函數(shù)名摧扇,使用這個(gè)可以自行在下面修改函數(shù)名稱,不使用則必須與C中的函數(shù)名相同挚歧。
這里注意[DllImport("EasyHelloWorlddll", EntryPoint = "sum", CallingConvention = CallingConvention.Cdecl)]
如果調(diào)用不加CallingConvertion扛稽,容易出現(xiàn)錯(cuò)誤

image.png

詳細(xì)見(jiàn):https://blog.csdn.net/wjeson/article/details/8263335

C++生成Dll

這里只是介紹最簡(jiǎn)單的生成方法,以后學(xué)多了考慮出個(gè)合集
同上C建立新工程滑负,只有代碼不同


image.png

C++ test.h

#pragma once //頭文件只編譯一次
extern "C" __declspec(dllexport) int __stdcall sum(int n1, int n2);

test.cpp

//test.cpp
#include "test.h"
#include <stdio.h>

int __stdcall sum(int a, int b) 
{
    return a + b;
}

C#上調(diào)用也是一樣的

{
    using System;
    using System.Runtime.InteropServices;
    class Program
    {
        [DllImport("EasyHelloWorlddll", EntryPoint = "sum")]
        public static extern int Sum(int a, int b);

        static void Main(string[] args)
        {
            Console.WriteLine(Sum(2,3));
            Console.ReadKey();
        }
}

關(guān)于32位和64位DLL

因?yàn)樾掳娴腢nity不支持32位框架dll的導(dǎo)入在张,于是需要?jiǎng)?chuàng)建64位dll,
創(chuàng)建方式矮慕,把之前的改為64位帮匾,同時(shí)把屬性中的exe換為dll〕睁可行

C++ 調(diào)用 C++

生成 myfish.h

#pragma once
extern "C" __declspec(dllexport) double __stdcall sum(double delta, double freq, double phase);

生成 myfish.cpp

#include "psm.h"
#include <stdio.h>
#include <math.h>

double __stdcall sum(double delta,double freq ,double phase) {
    double res =  100f * sin(delta+freq+ phase ) ;
    return res;
}

生成看情況,正澄列保可以x64 Release

生成myfish.dll

新建項(xiàng)目aaa.sln

屬性->VC++ 目錄->包含目錄,包含.h的目錄

屬性->VC++ 目錄->庫(kù)目錄,包含.lib的目錄

鏈接器->輸入->附加依賴項(xiàng)->添加myfish.lib

#include <iostream>
#include "myfish.h"
int main()
{
    std::cout << "Sum" << sum(7, 8, 0);
    std::cout << "Hello World!\n";
    system("pause");
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市痪寻,隨后出現(xiàn)的幾起案子螺句,更是在濱河造成了極大的恐慌,老刑警劉巖橡类,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛇尚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡顾画,警方通過(guò)查閱死者的電腦和手機(jī)取劫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)匆笤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人谱邪,你說(shuō)我怎么就攤上這事炮捧。” “怎么了惦银?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵咆课,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我璧函,道長(zhǎng)傀蚌,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任蘸吓,我火速辦了婚禮善炫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘库继。我一直安慰自己箩艺,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布宪萄。 她就那樣靜靜地躺著艺谆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拜英。 梳的紋絲不亂的頭發(fā)上静汤,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音居凶,去河邊找鬼虫给。 笑死,一個(gè)胖子當(dāng)著我的面吹牛侠碧,可吹牛的內(nèi)容都是我干的抹估。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼弄兜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼药蜻!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起替饿,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤语泽,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后盛垦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體湿弦,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年腾夯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了颊埃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蝶俱,死狀恐怖班利,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情榨呆,我是刑警寧澤罗标,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站积蜻,受9級(jí)特大地震影響闯割,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜竿拆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一宙拉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丙笋,春花似錦谢澈、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至怠肋,卻和暖如春敬鬓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背笙各。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工钉答, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人酪惭。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓希痴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親春感。 傳聞我的和親對(duì)象是個(gè)殘疾皇子砌创,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344