你用
我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、大慶ssl等。為超過(guò)千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的大慶網(wǎng)站制作公司
__declspec
(dllexport)
來(lái)寫DLL函數(shù)頭的話這個(gè)DLL只能被C或C++調(diào)用
將函數(shù)寫到
.DEF
文件的話可以讓所有編程語(yǔ)言都能調(diào)用
在編寫程序的時(shí)候往往需要調(diào)用到別的語(yǔ)言編寫的DLL文件,下面先來(lái)看一下在易語(yǔ)言中如何調(diào)用VC編寫的DLL呢,首先用VC編寫一個(gè)簡(jiǎn)單的DLL文件,代碼如下:
int WINAPI add(int x,int y)
{
return x+y;
}
這是一個(gè)簡(jiǎn)單的兩個(gè)數(shù)加法操作,返回兩個(gè)數(shù)相加的結(jié)果,這里我生成的是MFC DLL,并且需要在def中導(dǎo)出add函數(shù)。
下面用易語(yǔ)言來(lái)調(diào)用它,首先在易語(yǔ)言中需要插入一個(gè)DLL命令,代碼如下:
.版本 2
.DLL命令 調(diào)用CDLL, 整數(shù)型, "cdll.dll", "add"
.參數(shù) x, 整數(shù)型
.參數(shù) y, 整數(shù)型
并且保存工程文件與DLL文件在一起,否則可能會(huì)報(bào)找不到DLL的錯(cuò)誤.下面在按鈕中添加如下代碼:
.版本 2
.子程序 _按鈕1_被單擊
信息框 (調(diào)用CDLL (5, 5), 0, )
這樣我們傳遞了兩個(gè)數(shù)后就可以返回結(jié)果了,如下圖:
上圖的信息框顯示返回的結(jié)果是10,那么這就是正確的了,易語(yǔ)言調(diào)用VC的DLL需要注意類型,并且DLL函數(shù)需要WINAPI或stdcall,否則也會(huì)報(bào)錯(cuò)。
下面我們?cè)賮?lái)看一下VC如何調(diào)用易語(yǔ)言的DLL,還是先用易語(yǔ)言編寫一個(gè)DLL文件,建立一個(gè)DLL動(dòng)態(tài)鏈接庫(kù)工程,新建一個(gè)子程序,代碼如下:
.版本 2
.子程序 add, 整數(shù)型, 公開(kāi)
.參數(shù) x, 整數(shù)型
.參數(shù) y, 整數(shù)型
返回 (x + y)
下面我們用VC來(lái)調(diào)用這個(gè)DLL并且返回結(jié)果,代碼如下:
HINSTANCE hMod = LoadLibrary("e.dll");
typedef int(WINAPI *ADD)(int,int);
ADD myadd = (ADD)GetProcAddress(hMod,"add");
CString str;
str.Format("%d",myadd(5,5));
MessageBox(str);
FreeLibrary(hMod);
調(diào)用后結(jié)果如下圖:
這樣就得到了正確的結(jié)果了,需要注意的是易語(yǔ)言子程序必須公開(kāi),公開(kāi)也就是與VC中def文件導(dǎo)出是一樣的道理。
如果易語(yǔ)言編譯器容許您,那么就是可以的,例如keilc51編譯器和常用調(diào)試arm裸機(jī)程序,是可以在c語(yǔ)言語(yǔ)句中加入?yún)R編語(yǔ)言。
由于本人不了解易語(yǔ)言,無(wú)法確定其編譯器是否可以編譯c,但估計(jì)是不行。
那么說(shuō)回來(lái),如果這樣,程序就沒(méi)法寫了。實(shí)際大家是怎么做的呢。通常做法是將c語(yǔ)言程序編譯成dll文件,也就是我們所謂的庫(kù)文件。然后就可以實(shí)現(xiàn)調(diào)用了。這種文件我們經(jīng)常會(huì)在常見(jiàn)的程序中看到,原因就是代碼保密性好,并且更新很方便,關(guān)鍵在于可以多種語(yǔ)言交互。
當(dāng)然了,也可以吧所謂的易語(yǔ)言封裝成dll,被c調(diào)用,當(dāng)然如果他有這項(xiàng)功能的話。
如果一個(gè)c語(yǔ)言已經(jīng)編譯成可執(zhí)行程序了,比如exe文件,那么易語(yǔ)言端應(yīng)與c語(yǔ)言端進(jìn)行進(jìn)程通信,方可實(shí)現(xiàn)數(shù)據(jù)交互。那么進(jìn)程通信就有多種方式,那么就不贅述了。
說(shuō)下DLL的封裝,如果是c語(yǔ)言我們需要加入dll.h
dll.h中放入以下語(yǔ)句
#ifndef?_DLL_H_
#define?_DLL_H_
#if?BUILDING_DLL
#?define?DLLIMPORT?__declspec?(dllexport)
#else?/*?Not?BUILDING_DLL?*/
#?define?DLLIMPORT?__declspec?(dllimport)
#endif?/*?Not?BUILDING_DLL?*/
DLLIMPORT?void?HelloWorld?(void);
#include??"func.h"
#endif?/*?_DLL_H_?*/
程序中的,DLLIMPORT?void?HelloWorld?(void);,#include??"func.h"是例子,就是放你書寫的用c寫的函數(shù)聲明的地方。
而在你c語(yǔ)言原先放主函數(shù)的那個(gè)文件中應(yīng)該寫入以下內(nèi)容
/*?Replace?"dll.h"?with?the?name?of?your?header?*/
#include?"dll.h"
#include?windows.h
#include?stdio.h
#include?stdlib.h
BOOL?APIENTRY?DllMain?(HINSTANCE?hInst?????/*?Library?instance?handle.?*/?,
DWORD?reason????????/*?Reason?this?function?is?being?called.?*/?,
LPVOID?reserved?????/*?Not?used.?*/?)
{
switch?(reason)
{
case?DLL_PROCESS_ATTACH:
break;
case?DLL_PROCESS_DETACH:
break;
case?DLL_THREAD_ATTACH:
break;
case?DLL_THREAD_DETACH:
break;
}
/*?Returns?TRUE?on?success,?FALSE?on?failure?*/
return?TRUE;
}
我們看見(jiàn)有很多case,也有很多傳入?yún)?shù),最初可以不用管它,也可以使用。如需詳細(xì)配置,應(yīng)自行梳理再做決定。
另外一點(diǎn),對(duì)于高級(jí)語(yǔ)言和c語(yǔ)言清理現(xiàn)場(chǎng)的問(wèn)題,也就是被調(diào)用函數(shù)結(jié)束后由被調(diào)用函數(shù)清理?xiàng)#€是由下一個(gè)被執(zhí)行函數(shù)清理上一個(gè)函數(shù)的棧,這點(diǎn)很重要。兩種不同的調(diào)用方式將導(dǎo)致你雖然可以調(diào)用dll,但可能數(shù)據(jù)出錯(cuò)。這個(gè)問(wèn)題可以說(shuō)在VB與C的交互上面就可以體現(xiàn)了。__cdecl這個(gè)就是默認(rèn)c語(yǔ)言的棧處理方式。__stdcall是VB的處理方式,那么對(duì)于易語(yǔ)言,請(qǐng)您詳細(xì)查看后再做定論。
那么具體在c語(yǔ)言中提現(xiàn)就是,我們需要在函數(shù)前面加上__stdcall以告知編譯器采用此類編譯方式,應(yīng)用方法就如下面的聲明。
#ifndef?_FUNC_H_
#define?_FUNC_H_
#include????????"dll.h"
#include????winsock2.h
#include????"var.h"
DLLIMPORT?__stdcall?void?GetProgressNumFileIDPackageID(int?*PercentNum,int?*FileID,int?*PackageID);
DLLIMPORT?__stdcall?int?GetInfoNum(int?Mode);
DLLIMPORT?__stdcall?void?PutInfoNum(int?InfoNum,int?Mode);
DLLIMPORT?__stdcall?void?Demo0(void);
DLLIMPORT?__stdcall?void?Demo1(void);
DLLIMPORT?__stdcall?void?InitThreadCriticalSection(void);
DLLIMPORT?__stdcall?void?DeleteThreadCriticalSection(void);
#endif?/*_FUNC_H_*/
我聽(tīng)說(shuō)VB和易語(yǔ)言有相似之處那么我給出VB調(diào)用C語(yǔ)言DLL時(shí)候的函數(shù)書寫例子,以便您參考。
Public?Class?Form1
Private?Declare?Sub?NetToWork?Lib?"Client.dll"?(ByVal?IpAddr?As?String,?ByVal?Port?As?Integer,?ByVal?Mode?As?Integer)
Private?Declare?Function?StrToStruct?Lib?"Client.dll"?(ByVal?Str?As?String,?ByVal?Mode?As?Integer)?As?Integer
Private?Declare?Function?StructToStr?Lib?"Client.dll"?(ByVal?Str?As?String,?ByVal?Mode?As?Integer)?As?Integer
Private?Declare?Function?GetInfoNum?Lib?"Client.dll"?(ByVal?Mode?As?Integer)?As?Integer
Private?Declare?Sub?PutInfoNum?Lib?"Client.dll"?(ByVal?InfoNum?As?Integer,?ByVal?Mode?As?Integer)
Private?Declare?Sub?Demo0?Lib?"Client.dll"?()
Private?Declare?Sub?Demo1?Lib?"Client.dll"?()
.........
...
..
...
Private?Sub?ToolStripButton1_Click(ByVal?sender?As?System.Object,?ByVal?e?As?System.EventArgs)?Handles?ToolStripButton1.Click
'從text搜索關(guān)鍵詞?并讀取回鏈表數(shù)據(jù)?
Dim?Str?As?String
If?(ToolStripTextBox1.Text?=?"")?Then
MsgBox("內(nèi)容不能為空")
Else
Str?=?ToolStripTextBox1.Text
StrToStruct(Str,?SEND_SEARCH_0200)
Dim?Th0?As?Threading.Thread
Th0?=?New?Threading.Thread(AddressOf?DownFileList)
Th0.Start()
End?If
End?Sub
....
..
上程序但中StrToStruct(Str, SEND_SEARCH_0200)就是一個(gè)典型的VB調(diào)用DLL函數(shù)的例子。
那么如果給些相關(guān)的參考資料(C語(yǔ)言封裝DLL以及VB調(diào)用的問(wèn)題)
以便您對(duì)此更加了解。
C#編寫后的代碼是基于CLR公共語(yǔ)言運(yùn)行庫(kù)上的,是不同于C++輸出的傳統(tǒng)DLL,所以不能被易語(yǔ)言中調(diào)用,你所列的方法是適用于傳統(tǒng)VC++輸出的DLL,如API
網(wǎng)站題目:C編寫函數(shù)易語(yǔ)言調(diào)用 c調(diào)用易語(yǔ)言dll
網(wǎng)頁(yè)鏈接:http://vcdvsql.cn/article32/doiecpc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)、網(wǎng)站收錄、關(guān)鍵詞優(yōu)化、移動(dòng)網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)