Delphi 调用 c# 动态库-委托实现回调

由于Delphi 的局限性,有时候有的功能可能无法实现,需要借助与其他语言实现,比如C#,这里演示一下Delphi 如何调用C#动态库
  • c# 作为面向对象语言,其中所有的定义和Java 一样,一切皆对象,因此在编写动态链接库的时候需要符合com标准,而委托作为方法的指针,在Delphi 中调用需要把Delphi 中声明的方法地址转换成Ptr 即DWord 传递给C#的动态库,从而实现方法回调。
在C#中 建立一个.netframework 类库

image

image

设置COM

image

image

image

注意事项: 注册时使用命令 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);
    }
}

  1. 实现类
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 导入 ,导入可以编译为控件或者单元文件使用

image

代码下:

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.

效果:

image

posted @ 2023-04-11 12:05  丹心石  阅读(380)  评论(0编辑  收藏  举报