zoukankan      html  css  js  c++  java
  • delphi调用.Net中的dll

      COM 操作:
    编写C#dll的方法都一样,首先在vs2005中创建一个“类库”项目TestDll,
    using System.Runtime.InteropServices; 
    namespace TestDll
    {
         public   interface  I
    TestClass
        {
           void YourProcedure(string param1);
       
     } 

       [ClassInterface(ClassInterfaceType.None)]
        public   class 
    TestClass:ITestClass
        {
           public void 
    YourProcedure (string param1) 
           { 
           //自己的代码   
       } 
        } 
      

    }
    完成之后,设置项目的属性--应用程序--程序集信息--“Make assembly COM-Visible”为选中状态。编译之后得到 TestClass.dll,把此dll放到Delphi主程序目录下(就是你现在所写的delphi项目下)。打开vs2005自带的工具“Visual Studio 2005命令提示”,输入
    Regasm  路径/TestClass.dll 向系统注册此dll。

    Delphi程序调用此Dll方式有两种:
    一、打开vs2005自带的工具“Visual Studio 2005命令提示”,输入 TlbExp  路径/TestClass.dll 得到一个TestClass.tlb 文件。打开Delphi,选择“Project”--“import type library”找到刚才的TestClass.tlb,点击 CreateUnit,向delphi中引入一个com接口。
    delphi 调用代码如下:
     
     var aClass: TestClass; 
     
     begin
        aClass : =  CoTestClass.Create;
        aClass. YourProcedure ('参数'); 
      end; 
    二、不需生成tlb文件,仿照调用Excel的方式。代码如下:
    //注意:使用CreateOleObject时候,必须要uses Comobj 下,否则出错。 我自己加的
     var aClass: Variant;
    begin
      aClass:= CreateOleObject('TestDll.TestClass');
      aClass.YourProcedure ('参数');
    end;

    以上两种方法都可以调用成功,其中调用regasm.exe向系统注册dll是必需的。第一种方法需要生成tlb文件,并引入delphi中,操作繁琐,但可以看到接口的定义。第二种方法操作简单,但看不到接口的定义。
    ==============================================================
    本人用第二种方法已正常实现功能,但DLL中一些自动创建的方法无法在外部直接调用,需要DLL准备特定的接口函数
    另外的调用
    调用DLL有两种方法,一种是在应用程序装载时调用,另一种是在应用程序运行时调用。   
        
      (1)   装载时调用DLL   
        
      在调用DLL的Pas文件中,对DLL函数进行外部声明,声明应位于Implementation后,形式如下:   
        
      Implementation   
        
        Function   functionname(argment):Boolean;far;External   'DllName';     
        
      其中External关键字后面的引号内是DLL的文件名,该文件一般应放在系统的system目录下,或与调用它的项目同一目录。声明以后即可在Pas文件任何地方引用DLL函数。   
        
      装载时调用DLL的优点是速度较快,程序间也可共享代码。   
        
      (2)   运行时调用DLL   
        
      DLL的另一种调用方法是在运行时调用。这种方法要调用到Windows的API函数LoadLibrary,GetProcAddress,FreeLibrary等。此方法主要用于调用其它语言,特别是C++编译的DLL。   
        
      假定你欲调用的DLL中包括一个函数:   
        
      Function   checkpwd(pwd:string):boolean;export;     
        
      那么,首先在欲调用DLL的程序Type类型声明处加入一句: 
    注意:第一种是针对无返回值的,无返回值一般是procedure,而有返回值一般是function
    1, type
    Tcheckpwd=function(pwd:string):boolean;stdcall;  

        
    2  Type   
        
        Tcheckpwd=   function(pwd:string):boolean;     
        
      此句的作用如同C++中声明的函数指针。   
        
      然后定义如下变量∶   
        
      Var   
        
          aptr:TFarproc;   
        
        lhnd:THandle;   
        
        flag:boolean;     
        

    个人推荐这样定义:
    Var aptr:TFarproc;
    VAR lhnd:THandle;


      其中Aptr,lhnd两变量声明必须有,flag是DLL函数返回值,视情况而定。在调用DLL处加入如下语句进行DLL装载:   
        
      lhnd:=Loadlibrary('路径:DLL文件名');{如lhnd:=Loadlibrary('c:/project1.dll');   
        
        aptr:=GetprocAddress(lhnd,'checkpwd');     
        
      下面可直接调用DLL了:   
        
      flag:=Tcheckpwd(aptr)(   'pwd');{根据函数填相应的变量参数}     
        
      调用完以后,用FreeLibrary释放DLL占用的内存:   
        
      FreeLibrary(lhnd);   
       异常处理: 

    我用C#写的接口,封装成动态库,用DELPHI6调用时提示

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [Error] mscorlib_TLB.pas(5194): Type 'Byte' is not yet completely defined 
    [Error] mscorlib_TLB.pas(5209): Type 'Double' is not yet completely defined 
    [Error] mscorlib_TLB.pas(5235): Type 'Int64' is not yet completely defined 
    [Error] mscorlib_TLB.pas(5267): Type 'Single' is not yet completely defined 
    [Error] mscorlib_TLB.pas(5747): Illegal type in OLE automation section: 'Byte'
    [Error] mscorlib_TLB.pas(5754): Illegal type in OLE automation section: 'Single'
    [Error] mscorlib_TLB.pas(5755): Illegal type in OLE automation section: 'Double'
    [Error] mscorlib_TLB.pas(10874): Illegal type in OLE automation section: 'Byte'
    [Error] mscorlib_TLB.pas(10881): Illegal type in OLE automation section: 'Single'
    [Error] mscorlib_TLB.pas(10882): Illegal type in OLE automation section: 'Double'
    [Fatal Error] TestCOM_TLB.pas(60): Could not compile used unit 'mscorlib_TLB.pas'

    网上找到了解决办法如下:

    打开DELPHI6安装文件夹Bin libimp.sym文件,在文件尾部添加以下代码,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    ;;==============================================;; 
    ;; Map mscorlib CoClasses to better names ;; 
    ;;==============================================;; 
    [{BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}:TypeNames] 
    Byte=CLRByte 
    Double=CLRDouble 
    Single=CLRSingle 
    Int16=CLRInt16 
    Int32=CLRInt32 
    Int64=CLRInt64 
    String=CLRString 
    Object=CLRObject 
    Array=CLRArray 
    Enum=CLREnum 
    Boolean=CLRBoolean 
    Char=CLRChar 
    Guid=CLRGuid 
    Type=CLRType 
    Void=CLRVoid 
    Pointer=CLRPointer 
    Exception=CLRException

    保存,然后重要的一步,Import Type Library 引入动态库,重新Create unit接口定义文件。

     
     
     
  • 相关阅读:
    面向对象程序设计第五次作业(修改)
    C++作业 一
    面向对象程序设计第四次作业
    面向对象程序设计第三次作业
    C++学习笔记3
    C++学习笔记2
    C++学习笔记1
    面向对象程序设计作业二
    面向对象程序设计第二次作业
    随笔
  • 原文地址:https://www.cnblogs.com/http-www/p/3342229.html
Copyright © 2011-2022 走看看