日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DLL中导出函数的声明有两种方式

發(fā)布時(shí)間:2025/3/21 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DLL中导出函数的声明有两种方式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?本文引用自:VC編程時(shí)DLL中導(dǎo)出函數(shù)的聲明有兩種方式

一種方式是:在函數(shù)聲明中加上__declspec(dllexport);

另外一種方式是:采用模塊定義(.def)文件聲明,(.def)文件為鏈接器提供了有關(guān)被鏈接程序的導(dǎo)出、屬性及其他方面的信息。

方式一:在函數(shù)聲明中加上__declspec(dllexport)

/// 在動(dòng)態(tài)鏈接庫程序中

/// 聲明動(dòng)態(tài)鏈接庫(**.dll)的對外接口函數(shù)TestFuction

extern "C" __declspec(dllexport) int TestFuction(int nType,char *strPath,std::vector<string> &vecData)

{

?? do anything here

?? return 0;

}

/// 在外部希望調(diào)用動(dòng)態(tài)鏈接庫的程序中

/// 加載動(dòng)態(tài)鏈接庫(**.dll)并調(diào)用其對外接口TestFuction

void func()

{

? //typedef與函數(shù)TestFuction類型相同的函數(shù)指針為TESTDLL

? typedef int (_cdecl * TESTDLL)(int nType,char *strPath,std::vector<string> &vecData);

? HINSTANCE hmod;

? //加載動(dòng)態(tài)鏈接庫**.dll

? hmod =::LoadLibrary(_TEXT("dll相對路徑\\**.dll"));

? if(NULL == hmod)

? {

???? TRACE("加載**.dll失敗");

? }

? //定義一個(gè)與函數(shù)TestFuction類型相同的函數(shù)指針lpproc

? TESTDLL lpproc;

? //搜索**.dll中函數(shù)名為TestFuction的對外接口

? lpproc = (TESTDLL)GetProcAddress (hmod,"TestFuction");

? //如果搜索成功

? if(NULL != lpproc)

? {

???? int nType = 0;

???? char* strPath = "Data";

???? std::vector<string> vecData;

???? //通過函數(shù)指針lpproc調(diào)用**.dll的接口函數(shù)TestFuction

???? int nResult = (*lpproc)(nType,strPath,vecData);

? }

? //...

? //在恰當(dāng)?shù)臅r(shí)候釋放動(dòng)態(tài)鏈接庫**.dll

? FreeLibrary(hmod);

}

方式二:采用模塊定義(.def)文件聲明

首先創(chuàng)建 一個(gè)DLL程序(DllTestDef)

在*.cpp中

int __stdcall Add(int numa, int numb)

{

???? return (numa + numb);

}

int __stdcall Sub(int numa, int numb)

{

???? return (numa - numb);

}

然后創(chuàng)建一個(gè).def的文件,在里面加上

;DllTestDef.lib : 導(dǎo)出DLL函數(shù)

;作者:----

LIBRARY DllTestDef

EXPORTS

Add @ 1

Sub @ 2

最后創(chuàng)建一個(gè)測試程序:.cpp文件如下:

#include <iostream>

#include <windows.h>

using namespace std;

typedef int (__stdcall *FUN)(int, int);

HINSTANCE hInstance;

FUN?? fun;

int main()

{

?????? hInstance = LoadLibrary("DLLTestDef.dll");

?????? if(!hInstance)

?????????? cout << "Not Find this Dll" << endl;

?????? fun = (FUN)GetProcAddress(hInstance, MAKEINTRESOURCE(1));

?????? if (!fun)

?????? {

????????????? cout << "not find this fun" << endl;

?????? }

?????? cout << fun(1, 2) << endl;

?????? FreeLibrary(hInstance);

?????? return 0;

}

說明:

.def文件的規(guī)則為:

(1)LIBRARY語句說明.def文件相應(yīng)的DLL;

(2)EXPORTS語句后列出要導(dǎo)出函數(shù)的名稱。可以在.def文件中的導(dǎo)出函數(shù)名后加@n,表示要導(dǎo)出函數(shù)的序號(hào)為n(在進(jìn)行函數(shù)調(diào)用時(shí),這個(gè)序號(hào)將發(fā)揮其作用);

(3).def 文件中的注釋由每個(gè)注釋行開始處的分號(hào) (;) 指定,且注釋不能與語句共享一行。

(4)使用__declspec(dllexport)和使用.def文件是有區(qū)別的。

如果你的DLL是提供給VC用戶使用的,你只需要把編譯DLL時(shí)產(chǎn)生的.lib提供給用戶,

它可以很輕松地調(diào)用你的DLL。但是如果你的DLL是供VB、PB、Delphi用戶使用的,那么會(huì)產(chǎn)生一個(gè)小麻煩。

因?yàn)閂C++編譯器對于__declspec(dllexport)聲明的函數(shù)會(huì)進(jìn)行名稱轉(zhuǎn)換,如下面的函數(shù):

__declspec(dllexport) int __stdcall Add()

會(huì)轉(zhuǎn)換為Add@0,這樣你在VB中必須這樣聲明:

Declare Function Add Lib "DLLTestDef.dll" Alias "Add@0" () As Long

@后面的數(shù)由于參數(shù)類型不同而可能不同。這顯然不太方便。所以如果要想避免這種轉(zhuǎn)換,就要使用.def文件方式導(dǎo)出函數(shù)了。

總結(jié)

以上是生活随笔為你收集整理的DLL中导出函数的声明有两种方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。