博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
delphi调用.Net中的dll
阅读量:4589 次
发布时间:2019-06-09

本文共 3980 字,大约阅读时间需要 13 分钟。

  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\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接口定义文件。

 
 
 

转载于:https://www.cnblogs.com/http-www/p/3342229.html

你可能感兴趣的文章
c# 常见文件夹操作
查看>>
c# 计算目录的大小
查看>>
c# 常见文件操作
查看>>
c# Path类
查看>>
h3c 802.11协议的发展进程
查看>>
ISM无需授权使用的无线频率
查看>>
H3C 802.11b/g工作频段划分图
查看>>
H3C 802.11n
查看>>
H3C 802.11n的频宽模式
查看>>
H3C 40MHz频宽模式
查看>>
H3C Short GI
查看>>
H3C 帧聚合
查看>>
H3C WLAN相关组织和标准
查看>>
H3C 802.11网络的基本元素
查看>>
H3C IEEE 802.11无线局域网工作组
查看>>
H3C 802.11 MAC层工作原理
查看>>
H3C 802.11 WEP加密原理
查看>>
H3C 无线交换机和FIT AP的典型连接
查看>>
H3C FAT AP
查看>>
H3C STA>PC的数据转发
查看>>