zoukankan      html  css  js  c++  java
  • Delphi中开发的DLL如何被其它开发语言隐式调用

     
    Delphi中开发的DLL如何被其它开发语言隐式调用

           我曾经用Delphi中开发了《IAPWS-IF97/IFC67水和蒸汽性质计算软件包》。为了方便其它开发人
    员进行进一步的热能动力分析软件的开发,我编制了动态链接库(DLL)。其它开发人员也非专业程
    序设计人员,对于动态链接库的显式动态调用使用不好(觉得虽然灵活但烦琐),为了帮助他们用好
    我开发的“水和蒸汽性质计算动态链接库”,我开始对各种现代流行的程序设计语言(VC++、
    C++Builder、VC#、C# Builder、VB、VB.NET、Delphi、Delphi.NET等)隐式调用我的动态链接库的方
    法进行钻研,取得了一些进展。
           

           基于在如下几点,采用DLL 是合理的:
           1) 不同的程序使用相同的DLL ,这样只需要将DLL 在内存中装载一次,节省了内存的开销。
           2) 当某些内容需要升级的时候,如果使用DLL 只需要改变DLL 就可以了,而不需要把整个程
    序都进行更新。
           3) 由于DLL是独立于语言的,所以,当不同语言习惯的人共同开发一个大型项目的时候,使
    用DLL便于程序系统的交流,当然,Delphi开发的DLL也可以在诸如VB,C++ 等语言中使用。

    一、动态连接库构建

          我在Delphi中建立的DLL项目源代码的片断为:


    library WSPIF97;

    uses
        SysUtils,
        Registry,
        Classes,
        Math;

    {$R *.res}

    Const
        //  Initialize coefficients for region 4
        //  对区域4的基本公式的系数和指数进行初始化
        NReg4: ARRAY [1..10] OF Double=
        (
         1167.0521452767, -724213.16703206, -17.073846940092,  12020.82470247,  -3232555.0322333,
         14.91510861353,  -4823.2657361591,  405113.40542057, -0.23855557567849, 650.17534844798
        );

    // 已知温度(K),求对应的饱和压力(bar)
    // p^*:=1 Mpa:=10 bar        T^*:=1 K
    Function T2P(Const Temperature:Double):Double;
    Var
        DEL , aco , bco , cco : Double;
    Begin
        DEL := Temperature + NReg4[9] / (Temperature - NReg4[10]);
        aco := DEL*DEL + NReg4[1] * DEL + NReg4[2];
        bco := NReg4[3] * DEL*DEL + NReg4[4] * DEL + NReg4[5];
        cco := NReg4[6] * DEL*DEL + NReg4[7] * DEL + NReg4[8];
        Result := Power(2 * cco /(-bco + Power(bco*bco-4*aco*cco, 0.5)) , 4)* 10;
    End;

    Procedure T2P97(Const T:DOUBLE;Var P:DOUBLE; Var RANGE:Integer);EXPORT;STDCALL;
    Begin
        P:=T2P(T+T000C)/10;        //将温度单位℃变成 K,再将压力单位Bar变成MPa
    End;

    EXPORTS T2P97;

    end.

            我采用的调用协议为STDCALL,从DLL中导出的函数为T2P97。编译后生成动态链接库
    WSPIF97.DLL。


    二、动态连接库的调用

    2.1 Delphi

            只需在要调用WSPIF97.DLL动态链接库的单元中加上如下函数申明即可。

    //已知温度(℃),求饱和压力(MPa)?
    Procedure T2P97(Const T:Double;Var P:Double; Var Range:Integer);StdCall;External 'WSPIF97.DLL';


    2.2 Delphi.NET

            只需在要调用WSPIF97.DLL动态链接库的单元中加上如下函数申明即可。

    //已知温度(℃),求饱和压力(MPa)?
     [DllImport('WSPIF97.dll',CallingConvention = CallingConvention.StdCall,CharSet = CharSet.Unicode, PreserveSig = False)]
     procedure T2P97(Const T:Double;Var P:Double; Var Range:Integer);
     external;

    2.3 C++ Builder

        1.利用Borland提供的ImpLib.exe生成对应的导入库(WSPIF97.Lib),命令格式为:
        
            ImpLib WSPIF97.Lib  WSPIF97.Dll
            
        2.编写对应的头文件WSPIF97.h

    #define IMPORT_TYPE extern "C" __declspec(dllimport) __stdcall

    //已知温度(℃),求饱和压力(MPa)?
    IMPORT_TYPE void T2P97(double T,double & P,int & Range);
        
        3.直接把导入库文件(WSPIF97.Lib)和本头文件(WSPIF97.h)加进对应项目,
        在需要调用的单元中#include本头文件(WSPIF97.h)即可!

    2.4 C# Builder

             1.编写类文件(WSPIF97.cs)

    namespace WASP
    {
     public class WSPIF97
     {
      //已知温度(℃),求饱和压力(MPa)
      [DllImport("WSPIF97",EntryPoint="T2P97")]
      public static extern void T2P97(double T,ref double P,ref int Range);
     }
    }

            2.直接把类文件(WSPIF97.cs)加进对应项目,在需要调用函数的单元中引用本类文件的命名空
    间(using WASP)即可!


    2.5 VB

            只需在要调用WSPIF97.DLL动态链接库的VB项目中加上如下函数申明即可。

    Rem 已知温度(℃),求饱和压力(MPa)
    Private Declare Sub T2P97 Lib "WSPIF97.dll" (ByVal T As Double, ByRef P As Double, 
                                                                             ByRef Range As Integer)


    2.6 VB.NET

         1.编写类文件WSPIF97.vb。

    Imports System.Runtime.InteropServices

    Public Class WSPIF97
        REM 已知温度(℃),求饱和压力(MPa)?
        Declare Auto Sub T2P97 Lib "WSPIF97.dll" (ByVal T As Double, ByRef P As Double, 
                                                                               ByRef Range As Integer)
    End Class

        2.直接把类文件WSPIF97.vb加进对应项目即可!

    2.7 VC

        由于Microsoft没有提供通过DLL文件生成导入库LIB文件的工具,我们只能通过在VC++中
    编写一个同名称的空的DLL项目,令其产生对应的导入库LIB文件。

        1.编写def文件WSPIF97.def。

    LIBRARY     WSPIF97.DLL

    EXPORTS
        T2P97        
        
        2.编写WSPIF97.cpp文件。

    #include "stdafx.h"
    BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
          )
    {
        return TRUE;
    }

    //已知温度(℃),求饱和压力(MPa)
    extern "C" void __stdcall  T2P97(double T,double & P,int & Range){ }

        3. 通过WSPIF97.cpp和WSPIF97.def编译生成对应的导入库文件WSPIF97.lib。

        4.编写对应的头文件WSPIF97.H。

    #pragma comment(lib,"WSPIF97.lib")

    #define IMPORT_TYPE extern "C" _declspec(dllimport) 

    //已知温度(℃),求饱和压力(MPa)
    IMPORT_TYPE void _stdcall T2P97(double T,double & P,int & Range);

          5.直接把前面得到的导入库文件(WSPIF97.Lib)和头文件(WSPIF97.h)加进对应项目,
    在需要调用的单元中#include头文件(WSPIF97.h)即可!

    2.8  VC.NET

        1.编写头文件WSPIF97.h。

    //已知温度(℃),求饱和压力(MPa)?
    [DllImport("WSPIF97.dll")]  extern void T2P97(double T,double & P,int & Range);

        2.直接把头文件(WSPIF97.h)加进对应项目,在需要调用的单元中#include头文件
    (WSPIF97.h)即可!

    2.9 VC#

             1.编写类文件(WSPIF97.cs)

    using System;
    using System.Runtime.InteropServices;

    namespace WASP
    {
     public class WSPIF97
     {
      //已知温度(℃),求饱和压力(MPa)?
      [DllImport("WSPIF97",EntryPoint="T2P97")]
      public static extern void T2P97(double T,ref double P,ref int Range);
     }
    }

            2.直接把类文件(WSPIF97.cs)加进对应项目,在需要调用函数的单元中引用本类文件的命名空
    间(using WASP)即可!

  • 相关阅读:
    《算法竞赛入门经典》—— 5.2.6 栈、队列与优先队列
    《算法:C语言实现》—— 第二部分 —— 第3章 —— 基本数据结构
    《算法:C语言实现》—— 第二部分 —— 第3章 —— 基本数据结构
    《算法:C语言实现》—— 第二部分 —— 第3章 —— 基本数据结构
    Broken Keyboard (a.k.a. Beiju Text)
    Broken Keyboard (a.k.a. Beiju Text)
    Broken Keyboard (a.k.a. Beiju Text)
    mongodb实战聚合 组内排序
    mongodb实战聚合 组内排序
    MongoDB基础篇:MongoDB Shell命令大全
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2941004.html
Copyright © 2011-2022 走看看