Delphi 调用 c# 动态库-委托实现回调
由于Delphi 的局限性,有时候有的功能可能无法实现,需要借助与其他语言实现,比如C#,这里演示一下Delphi 如何调用C#动态库
- c# 作为面向对象语言,其中所有的定义和Java 一样,一切皆对象,因此在编写动态链接库的时候需要符合com标准,而委托作为方法的指针,在Delphi 中调用需要把Delphi 中声明的方法地址转换成Ptr 即DWord 传递给C#的动态库,从而实现方法回调。
在C#中 建立一个.netframework 类库
设置COM
注意事项: 注册时使用命令 regasm x:\xx\xx.dll /tlb 需要在管理员模式下。系统自动生成的tlb文件可能无法使用,最好通过此命令重新注册。
* C# Code: 1. 接口namespace WebSocketLib
{
public delegate void ProcessDelegate(string msg);
public interface InfWebSocketService
{
string Open(string url);
void SetDelegate(long ptr);
}
}
- 实现类
using System;
using System.Runtime.InteropServices;
using System.Timers;
namespace WebSocketLib
{
[ClassInterface(ClassInterfaceType.None)]
public class ImpWebSocketService : InfWebSocketService
{
private ProcessDelegate delProcess = null;
private Timer timer = new Timer();
public string Open(string url)
{
timer.Interval = 1000;
timer.Elapsed += Timer_Elapsed;
timer.Start();
return $"你确认要打开:{url} 的WebSocket 连接吗?" ;
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (delProcess != null)
{
delProcess($"时间:{DateTime.Now.ToLongTimeString()},心跳检测");
}
}
public void SetDelegate(long ptr)
{
IntPtr intPtr = new IntPtr(ptr);
delProcess = (ProcessDelegate)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(ProcessDelegate));
}
}
}
Delphi 导入 ,导入可以编译为控件或者单元文件使用
代码下:
unit uWebSocketClientDemo;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
btnOpen: TButton;
Memo1: TMemo;
procedure btnOpenClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses ComObj,WebSocketLib_TLB; //引入导入的文件WebSocketLib_TLB ComObj 可以不用
var
client:InfWebSocketService;
procedure callback(s:PAnsiChar);stdcall; //注意,这里的参数一定要使用PAnsichar 指针字符串,不要用string
begin
Form1.Memo1.Lines.Add(s);
end;
procedure TForm1.btnOpenClick(Sender: TObject);
var
inf:InfWebSocketService;
s:string;
begin
inf:=CoImpWebSocketService.Create();
inf.SetDelegate(dword(@callback));
s:=inf.Open('Delphi 7');
ShowMessage(s);
end;
end.