delphi调用.Net中的dll

COM 操作:

编写C#dll的方法都一样,首先在vs2005中创建一个“类库”项目TestDll,

using System.Runtime.InteropServices;

namespace TestDll

//自己的代码

二、不需生成tlb文件,仿照调用Excel的方式。代码如下:

//注意:使用CreateOleObject时候,必须要uses Comobj 下,否则出错。 我自己加的

var aClass: Variant;

begin

aClass:= CreateOleObject('TestDll.TestClass');

aClass.('参数');

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'isnot yet completely defined

[Error] mscorlib_TLB.pas(5209): Type'Double'isnot yet completely defined

[Error] mscorlib_TLB.pas(5235): Type'Int64'isnot yet completely defined

[Error] mscorlib_TLB.pas(5267): Type'Single'isnot yet completely defined

[Error] mscorlib_TLB.pas(5747): Illegal typeinOLE automation section:'Byte'

[Error] mscorlib_TLB.pas(5754): Illegal typeinOLE automation section:'Single'

[Error] mscorlib_TLB.pas(5755): Illegal typeinOLE automation section:'Double'

[Error] mscorlib_TLB.pas(10874): Illegal typeinOLE automation section:'Byte'

[Error] mscorlib_TLB.pas(10881): Illegal typeinOLE automation section:'Single'

[Error] mscorlib_TLB.pas(10882): Illegal typeinOLE automation section:'Double'

[Fatal Error] TestCOM_TLB.pas(60): Could not compile used unit'mscorlib_TLB.pas'

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

打开DELPHI6安装文件夹\Bin\tlibimp.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接口定义文件。