VB呼叫C程式的方法—動態連結庫法 (轉)

worldblog發表於2007-12-06
VB呼叫C程式的方法—動態連結庫法 (轉)[@more@]

摘 要
 文中介紹了一種實現VBC語言的方法-動態連線庫法,給出了動態連結庫制
作的一般,透過例項描述了動態連線庫的實現及其製做方法、步驟,這種方法具有
普遍的意義。
關鍵詞 動態連線庫DLL C程式

一、引言

 ( 以下簡稱VB)是一種視覺化的面向的程式語言,以其程式設計簡單、快捷
等特點,深受廣大程式設計師的青睞。利用VB開發介面友好、操作方便的只需
很短的時間。但是VB執行速度較慢,對於龐大的科學計算問題,VB的這種慢速會使人難
以忍受。C語言是國際上非常流行的一種中級程式語言,以其靈活、高效等優點而獲得廣
泛應用,許多的應用程式都是用C語言在DOS環境下編寫而成。那麼如何發揮VB和C這兩
種語言的優勢,用VB設計一種良好的for windows介面來呼叫C語言程式,即實現VB呼叫C
語言程式呢?現有的文獻只提到動態連結庫(以下簡稱DLL)可以將這兩種語言連線起來,
但有講動態連結庫DLL的製做及其程式設計方法。本文詳細介紹了Borland C環境下製作動態鏈
接庫以及VB呼叫for dos動態連結庫的的方法、步驟,並透過例項描述VB呼叫C程式的全過
程。

二、用Borland C編寫DLL程式的方法

 要想實現VB呼叫C程式,首先需要用Borland C編寫動態連線庫DLL程式(假設DLL程式
取名為example)。動態連結庫包含四個:C語言源程式(.C)、模組定義檔案
(.DEF)、原型檔案(.H)和工程檔案(.PRJ)。下面分別詳細介紹一下這四種檔案
的具體結構。
1、編寫C語言源程式的框架:
C語言源程式(example.C),它包括三種函式:入口函式、輸出函式和終止函式。其具體
結構如下:
/*************************************/
/* 檔名: example.C */
/*************************************/
#include
/***********入口函式***********/
int FAR PASCAL LibMain ( HANDLE hInstance,
wDataSeg,
WORD cbHeapSize,
LPSTR lpszCmdLine )
{
if (cbHeapSize!=0)
UnlockData(0);
return (1);
}

/***********輸出函式***********/

int FAR PASCAL example(int param1,...,char param n)
{
...... /*C語言應用程式*/
}
/***********終止函式***********/
int FAR PASCAL WEP ( int /*SystemExit*/ )
{
return(1);
}
 以上各組成部分引數的含義:Windows.h標頭檔案,它包含有資料型別的定義、入口
點定義和其它有用的引數資訊。PASCAL說明符定義該程式的傳遞引數和淨化堆疊的協定
(注意:DLL外部傳送的指標必須是遠指標FAR)。LibMain帶四個引數:
hInstance、 wDataSeg、cbHeapSize和lpszCmdLine。第一個引數hInstance是DLL事例句
柄, wDataSeg引數是資料段(DS)暫存器值,cbHeapSize引數是在模組定義檔案中定義
的堆的大小,LibMain 使用該值使本地堆初始化。lpszCmdLine引數包括命令列資訊,但
很少被DLL使用。一般來說,這四個引數是製作DLL通用的引數。
如果不想讓DLL資料被封住,那麼必須呼叫unlockdata恢復正常的非鎖狀態,如果DLL初始
化已經成功,DLL則返回1,若不成功則返回0值,且 DLL退出。
DLL的輸出函式實現所要完成的任務,這部分是DLL的核心。它與一般C語言程式不同
之處在於無scanf函式。所有的外部指標都是遠指標FAR。畫直線函式要用lo函式。
DLL包括一個終止函式,終止函式有時稱為退出函式,它的名字必須是WEP。且它可以被
包括在DLL模組定義檔案的EXPORTS段中。
2、模組定義檔案(.DEF)的結構和各段的意義
模組定義檔案的結構如下:
/*************************************/
/* 檔名: example.DEF */
/*************************************/
LIBRARY example /* DLLname */
DESCRIPTION ' example.DLL'
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 1024
EXPORTS
example @1
WEP @2
 關鍵字LIBRARY是把這個模組視為一個DLL,庫的名字example跟在其後,且必須與該庫
的名字、DEF中的DLL的檔名相一致。DESCRIPTION語句採用一個字串,其長度可達
128 個字元,通常用它來儲存模組描述的資訊。EXETYPE windows語句每個windows應用程
序和 DLL都需要。DATA語句定義該庫資料段的屬性,關鍵字MOVEABLE允許記憶體管
理程式在 必要時移動記憶體段,關鍵字SINGLE是DLL必要,因為DLL總是有一個單一資料段,
而不管訪 問它的應用程式的數量。HEAPSIZE語句用來定義一個DLL區域性堆的初始規模,
區域性內 存分配的DLL必須在庫啟動時使該堆初始化,堆的大小被傳送給DLL的LiEntry
的程式。然 後用該堆的大小呼叫Locallnit使DLL的區域性堆初始化。
 EXEPORTS語句定義將被用作來自應用程式或來自其它DLL入口點的程式,windows利用
這個資訊建立一個序數入口值,序數入口值是一個的值,允許動態連線機制更快塊操
作且使用較少的記憶體。
 一般來說,模組定義檔案(.DEF)的結構除取動態庫的名字不同外,其它結構都是固定
的。
3.建立原形函式檔案(.H)
原形函式的功能是進一步宣告呼叫函式的函式名和傳遞的引數,其形式為:
/*************************************/
/* 檔名: example.H */
/*************************************/
extern "C" int _export FAR PASCAL example(int param1,...,char param n) ;
4.建立工程檔案(.PRJ)
 工程檔案中包含有example.C、example.DEF兩個檔案後,然後編譯連線生成動態連結
庫即可。
 以上是製作動態連線庫的框架,現在透過一個例項介紹製作動態連結庫的方法。如要
求程式完成功能為:開啟一個資料檔案讀出前兩個資料,將這兩個數與所傳遞的兩個引數
相加,返回它們的和。設該DLL程式的名字為ADD。
第一步:在Borland C++環境下編輯.C檔案、.DEF檔案和.H檔案,並建立.PRJ檔案。如
(1)編寫C語言源程式清單:
/*************************************/
/* 檔名: ADD.C */
/*************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include "c:ADD.h"
/*入口函式*/
int FAR PASCAL LibMain (HANDLE hInstance ,
WORD wDataSeg ,
WORD cbHeapSize,
LPSTR lpszCmdLine )
{
if (cbHeapSize!=0)
UnlockData(0);
return 1;
}
/*輸出函式*/
int FAR PASCAL ADD(int x,int y,char *filein)
{ int a,b;
fp=fopen(filein,"r");
if(fp==NULL) { exit(0);}
int temp1=0,temp2=0;
fscanf(fp,"%d",&a);
fscanf(fp,"%d",&b);
temp1=x+a;
temp2=y+b;
temp1=temp1+temp2;
fclose(fp);
return(temp1);
}
/*退出函式*/
int FAR PASCAL WEP ( int/*SystemExit*/ )
{
return(1);
}
2)ADD.DEF檔案的程式清單:
/*************************************/
/* 檔名: ADD.H */
/*************************************/
LIBRARY ADD
DESCRIPTION 'ADD.DLL'
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 1024
EXPORTS
ADD @1
WEP @2
(3)ADD.H程式清單:
/*************************************/
/* 檔名: ADD.H */
/*************************************/
extern "C" int _export FAR PASCAL add(int x,int y,char *filein) ;
(4)建立工程檔案:
在Borland C++環境下的project項中開啟open project file項並建立ADD.prj,在add
item中加入ADD.C檔案和ADD.DEF檔案即可建立工程檔案。
第二步,在Borland C的options項的Applation中選擇Windows DLL,再在Compile中選擇
Build all,這樣就可生成動態連結庫ADD.DLL供VB呼叫。

三、VB3.0呼叫動態連結庫DLL方法

 製作好DLL之後,就可以用VB呼叫它,實現VB呼叫C程式。VB程式要使用DLL中的函
數, 首先必須要有特殊的宣告,用Declare宣告語句在窗體級或模組級或全域性模組的程式碼
宣告段進行宣告,將動態連結庫中的函式宣告到VB中,供VB程式呼叫。
語句格式為:Declare Sub 過程名Lib摽鈹黚_n[ Alias " 別名]([ByVal 引數AS型別]),
或為Declare Function函式名Lib摽鈹黚_衃 Alias " 別名]([ByVal 引數AS型別])AS
型別在宣告中首先用Declare關鍵字表示宣告DLL中的函式。在C語言中有的函式型別為
VOID,它表示不具有返回值,則必須用關鍵字Sub將其宣告成過程。有的函式具有返回
值,則必須用關鍵字Function將其宣告成函式,並且在宣告語句的最後要用AS關鍵字指明
函式返回值的型別。
例如上面的ADD.DLL在VB中就可以宣告為:
Declare Function ADD Lib撫c:ADD.dll敓―ByVal X AS Integer, ByVal Y AS Integer ,ByVal filein as string)AS Integer
透過此宣告語句將函式ADD宣告到VB中,便可直接呼叫。

四、結束語

 以上詳細介紹了Borland C環境下製作動態連結庫以及VB呼叫for dos動態連結庫的方
法、步驟,並透過例項說明VB呼叫C語言程式的方法。舉例程式ADD經VB3.0編譯,在486
微機上透過。本文介紹的方法具有廣泛的意義,也完全適用於C++ 語言程式。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988880/,如需轉載,請註明出處,否則將追究法律責任。

相關文章