为了账号安全,请及时绑定邮箱和手机立即绑定

从 Delphi 调用 C# Dll-Export - 以字符串作为参数的回调

从 Delphi 调用 C# Dll-Export - 以字符串作为参数的回调

C#
繁花如伊 2021-11-14 10:47:27
我正在尝试从 C# 导出一个函数并使用 delphi 应用程序调用这个函数。被调用的函数应该得到一个回调作为参数。此回调将字符串作为参数。csharp_export_function(callbackfct(str))我设法调用了一个 C# 函数,它写入一个字符串并在 delphi 中使用这个字符串。我还设法调用了一个带有回调作为参数的 C# 函数,并使用了这个回调。但是我无法获得带有字符串作为参数运行的回调。当在回调函数中使用字符串时,我在 Delphi 中收到访问冲突异常。那里的字符串似乎是空的。因此,执行了 callbak,但不能使用该字符串。我正在使用 Robert Giesecke 的 C# 的 DllExport。德尔福 XE5 和 VS2012。这是代码:德尔福:interfaceuses  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;type  TForm2 = class(TForm)    Button1: TButton;    Button2: TButton;    Edit1: TEdit;    Edit2: TEdit;    Button4: TButton;    Edit4: TEdit;    procedure Button1Click(Sender: TObject);    procedure Button2Click(Sender: TObject);    procedure Button4Click(Sender: TObject);  private  public  end;  TStringCallback = procedure(out str:PAnsiChar);  procedure strCallBack(fct: TStringCallback); cdecl; external 'csTest.dll';var  Form2: TForm2;implementation{$R *.dfm}//*************************************************************//callback with stringprocedure writeEdit2(out str: PAnsiChar);begin  Form2.Edit2.Text := str;      //!! exception access violation !!end;procedure TForm2.Button2Click(Sender: TObject);begin  strCallBack(writeEdit2);end;//*************************************************************end.C#:using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using RGiesecke.DllExport;using System.Runtime.InteropServices;namespace cs_dcsSrv{    public class Class1    {        public delegate void strCB([MarshalAs(UnmanagedType.BStr)] String s);        [DllExport("strCallBack", CallingConvention = CallingConvention.Cdecl)]        public static void stringCallback(strCB fct)        {            String str = "hello from C#";            fct(str);        }    }}提前致谢。
查看完整描述

2 回答

?
慕妹3146593

TA贡献1820条经验 获得超9个赞

您不需要out在此处用于参数传递,并且调用约定与您的委托不匹配。委托的相关代码是,在 C# 端

public delegate void strCB(string s);

在德尔福方面

TStringCallback = procedure(str: PAnsiChar); stdcall;

我一直像你一样坚持使用 ANSI 字符串,但如果这是我的代码,我个人会使用 Unicode。


查看完整回答
反对 回复 2021-11-14
?
当年话下

TA贡献1890条经验 获得超9个赞

我正在尝试从 C# 导出一个函数并使用 delphi 应用程序调用这个函数。被调用的函数应该得到一个回调作为参数。此回调将字符串作为参数。csharp_export_function(callbackfct(str))


我设法调用了一个 C# 函数,它写入一个字符串并在 delphi 中使用这个字符串。我还设法调用了一个带有回调作为参数的 C# 函数,并使用了这个回调。


但是我无法获得带有字符串作为参数运行的回调。当在回调函数中使用字符串时,我在 Delphi 中收到访问冲突异常。那里的字符串似乎是空的。因此,执行了 callbak,但不能使用该字符串。


我正在使用 Robert Giesecke 的 C# 的 DllExport。德尔福 XE5 和 VS2012。


这是代码:


德尔福:


interface


uses

  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,

  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;


type

  TForm2 = class(TForm)

    Button1: TButton;

    Button2: TButton;

    Edit1: TEdit;

    Edit2: TEdit;

    Button4: TButton;

    Edit4: TEdit;

    procedure Button1Click(Sender: TObject);

    procedure Button2Click(Sender: TObject);

    procedure Button4Click(Sender: TObject);

  private


  public


  end;


  TStringCallback = procedure(out str:PAnsiChar);


  procedure strCallBack(fct: TStringCallback); cdecl; external 'csTest.dll';

var

  Form2: TForm2;


implementation


{$R *.dfm}


//*************************************************************

//callback with string

procedure writeEdit2(out str: PAnsiChar);

begin

  Form2.Edit2.Text := str;      //!! exception access violation !!

end;


procedure TForm2.Button2Click(Sender: TObject);

begin

  strCallBack(writeEdit2);

end;

//*************************************************************


end.

C#:


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using RGiesecke.DllExport;

using System.Runtime.InteropServices;


namespace cs_dcsSrv

{

    public class Class1

    {

        public delegate void strCB([MarshalAs(UnmanagedType.BStr)] String s);


        [DllExport("strCallBack", CallingConvention = CallingConvention.Cdecl)]

        public static void stringCallback(strCB fct)

        {

            String str = "hello from C#";

            fct(str);

        }

    }

}

提前致谢。


查看完整回答
反对 回复 2021-11-14
  • 2 回答
  • 0 关注
  • 618 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信