程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> Visual Basic語言 >> VB綜合教程 >> VB調用C程序動態鏈接庫的方法

VB調用C程序動態鏈接庫的方法

編輯:VB綜合教程
摘要
  文中介紹了一種實現VB調用C語言程序的方法-動態連接庫法,給出了動態鏈接庫制作的一般框架,通過實例描述了動態連接庫的實現及其制做方法、編程步驟,這種方法具有普遍的意義。

關鍵詞:VB,動態連接庫DLL,C程序
  
  一、引言
  
  VisualBasic(以下簡稱VB)是一種可視化的面向對象的編程語言,以其編程簡單、快捷等特點,深受廣大WINDOWS程序員的青睐。利用VB開發界面友好、操作方便的軟件只需很短的時間。但是VB運行速度較慢,對於龐大的科學計算問題,VB的這種慢速會使人難以忍受。C語言是國際上非常流行的一種中級編程語言,以其靈活、高效等優點而獲得廣泛應用,許多的應用程序都是用C語言在DOS環境下編寫而成。那麼如何發揮VB和C這兩種語言的優勢,用VB設計一種良好的forwindows界面來調用C語言程序,即實現VB調用C語言程序呢?現有的文獻只提到動態鏈接庫(以下簡稱DLL)可以將這兩種語言連接起來,但沒有講動態鏈接庫DLL的制做及其編程方法。本文詳細介紹了BorlandC環境下制作動態鏈接庫以及VB調用fordos動態鏈接庫的的方法、步驟,並通過實例描述VB調用C程序的全過程。
  
  二、用BorlandC編寫DLL程序的方法
  
  要想實現VB調用C程序,首先需要用BorlandC編寫動態連接庫DLL程序(假設DLL程序取名為example)。動態鏈接庫包含四個文件:C語言源程序(.C)、模塊定義文件(.DEF)、原型函數文件(.H)和工程文件(.PRJ)。下面分別詳細介紹一下這四種文件的具體結構。
  1、編寫C語言源程序的框架:
  C語言源程序(example.C),它包括三種函數:入口函數、輸出函數和終止函數。其具體結構如下:
  /*************************************/
  /*文件名:example.C*/
  /*************************************/
  #include<windows.h>
  /***********入口函數***********/
  intFARPASCALLibMain(HANDLEhInstance,
  WORDwDataSeg,
  WORDcbHeapSize,
  LPSTRlpszCmdLine)
  {
  if(cbHeapSize!=0)
  UnlockData(0);
  return(1);
  }
  
  /***********輸出函數***********/
  
  intFARPASCALexample(intparam1,...,charparamn)
  {
  ....../*C語言應用程序*/
  }
  /***********終止函數***********/
  intFARPASCALWEP(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模塊定義文件的EXPORTS段中。
  2、模塊定義文件(.DEF)的結構和各段的意義
  模塊定義文件的結構如下:
  /*************************************/
  /*文件名:example.DEF*/
  /*************************************/
  LIBRARYexample/*DLLname*/
  DESCRIPTION'example.DLL'
  EXETYPEWINDOWS
  CODEPRELOADMOVEABLEDISCARDABLE
  DATAPRELOADMOVEABLESINGLE
  HEAPSIZE1024
  EXPORTS
  example@1
  WEP@2
  關鍵字LIBRARY是把這個模塊視為一個DLL,庫的名字example跟在其後,且必須與該庫的名字、DEF中的DLL的文件名相一致。DESCRIPTION語句采用一個字符串,其長度可達128個字符,通常用它來保存模塊描述的信息。EXETYPEwindows語句每個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_exportFARPASCALexample(intparam1,...,charparamn);
  4.建立工程文件(.PRJ)
  工程文件中包含有example.C、example.DEF兩個文件後,然後編譯連接生成動態鏈接庫即可。
  以上是制作動態連接庫的框架,現在通過一個實例介紹制作動態鏈接庫的方法。如要求程序完成功能為:打開一個數據文件讀出前兩個數據,將這兩個數與所傳遞的兩個參數相加,返回它們的和。設該DLL程序的名字為ADD。
  第一步:在BorlandC 環境下編輯.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"
  /*入口函數*/
  intFARPASCALLibMain(HANDLEhInstance,
  WORDwDataSeg,
  WORDcbHeapSize,
  LPSTRlpszCmdLine)
  {
  if(cbHeapSize!=0)
  UnlockData(0);
  return1;
  }
  /*輸出函數*/
  intFARPASCALADD(intx,inty,char*filein)
  {inta,b;
  fp=fopen(filein,"r");
  if(fp==NULL){exit(0);}
  inttemp1=0,temp2=0;
  fscanf(fp,"d",&a);
  fscanf(fp,"d",&b);
  temp1=x a;
  temp2=y b;
  temp1=temp1 temp2;
  fclose(fp);
  return(temp1);
  }
  /*退出函數*/
  intFARPASCALWEP(int/*SystemExit*/)
  {
  return(1);
  }
  2)ADD.DEF文件的程序清單:
  /*************************************/
  /*文件名:ADD.H*/
  /*************************************/
  LIBRARYADD
  DESCRIPTION'ADD.DLL'
  EXETYPEWINDOWS
  CODEPRELOADMOVEABLEDISCARDABLE
  DATAPRELOADMOVEABLESINGLE
  HEAPSIZE1024
  EXPORTS
  ADD@1
  WEP@2
  (3)ADD.H程序清單:
  /*************************************/
  /*文件名:ADD.H*/
  /*************************************/
  extern"C"int_exportFARPASCALadd(intx,inty,char*filein);
  (4)建立工程文件:
  在BorlandC 環境下的project項中打開openprojectfile項並建立ADD.prj,在add
  item中加入ADD.C文件和ADD.DEF文件即可建立工程文件。
  第二步,在BorlandC的options項的Applation中選擇WindowsDLL,再在Compile中選擇Buildall,這樣就可生成動態鏈接庫ADD.DLL供VB調用。
  
  三、VB3.0調用動態鏈接庫DLL方法
  
  制作好DLL之後,就可以用VB調用它,實現VB調用C程序。VB程序要使用DLL中的函數,首先必須要有特殊的聲明,用Declare聲明語句在窗體級或模塊級或全局模塊的代碼聲明段進行聲明,將動態鏈接庫中的函數聲明到VB中,供VB程序調用。
  語句格式為:DeclareSub過程名Lib[Alias"別名]([ByVal參數AS類型]),或為DeclareFunction函數名Lib[Alias"別名]([ByVal參數AS類型])AS類型在聲明中首先用Declare關鍵字表示聲明DLL中的函數。在C語言中有的函數類型為VOID,它表示不具有返回值,則必須用關鍵字Sub將其聲明成過程。有的函數具有返回值,則必須用關鍵字Function將其聲明成函數,並且在聲明語句的最後要用AS關鍵字指明函數返回值的類型。
  例如上面的ADD.DLL在VB中就可以聲明為:
  DeclareFunctionADDLibc:ADD.dll―ByValXASInteger,ByValYASInteger,ByValfileinas
  string)ASInteger
  通過此聲明語句將函數ADD聲明到VB中,便可直接調用。
  
  四、結束語
  
  以上詳細介紹了BorlandC環境下制作動態鏈接庫以及VB調用fordos動態鏈接庫的方法、步驟,並通過實例說明VB調用C語言程序的方法。舉例程序ADD經VB3.0編譯,在486微機上調試通過。本文介紹的方法具有廣泛的意義,也完全適用於C 語言程序。

->

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved