VB調用C程序的方法—動態鏈接庫法
發表于:2007-07-14來源:作者:點擊數:
標簽:
摘 要 文中介紹了一種實現VB調用C語言程序的方法-動態連接庫法,給出了動態鏈接庫制 作的一般框架,通過實例描述了動態連接庫的實現及其制做方法、編程步驟,這種方法具有 普遍的意義。 關鍵詞 VB 動態連接庫DLL C程序 一、引言 Visual Basic( 以下簡稱VB)是
摘 要
文中介紹了一種實現VB調用C語言程序的方法-動態連接庫法,給出了動態鏈接庫制
作的一般框架,通過實例描述了動態連接庫的實現及其制做方法、編程步驟,這種方法具有
普遍的意義。
關鍵詞 VB 動態連接庫DLL C程序
一、引言
Visual Basic( 以下簡稱VB)是一種可視化的
面向對象的編程語言,以其編程簡單、快捷
等特點,深受廣大
WINDOWS程序員的青睞。利用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 <windows.h>
/***********入口函數***********/
int FAR PASCAL LibMain ( HANDLE hInstance,
WORD 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頭文件,它包含有數據類型的定義、API入口
點定義和其它有用的參數信息。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。畫直線函數要用lineto函數。
DLL包括一個終止函數,終止函數有時稱為退出函數,它的名字必須是WEP。且它可以被
包括在DLL模塊定義文件的E
XPORTS段中。
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 <
iostream.h>
#include <conio.h>
#include <io.h>
#include <alloc.h>
#include <stdlib.h>
#include <windows.h>
#include <math.h>
#include <stdio.h>
#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++ 語言程序。
原文轉自:http://www.anti-gravitydesign.com