从 Delphi 调用 C# Dll-Export - 以字符串作为参数的回调 - Robert Giesecke DLLExport
Call C# Dll-Export from Delphi - Callback with String as parameter - Robert Giesecke DLLExport
我正在尝试从 C# 导出函数并使用 delphi 应用程序调用该函数。
被调用的函数应该得到一个回调作为参数。此回调将字符串作为参数。
csharp_export_function(callbackfct(str))
我设法调用了一个 C# 函数,该函数写入一个字符串并在 delphi 中使用该字符串。
我还设法调用了一个带有回调作为参数的 C# 函数,并使用了这个回调。
但我无法获得以字符串作为参数的回调 运行。
在回调函数中使用字符串时,我在 Delphi 中遇到访问冲突异常。那里的字符串似乎是空的。
所以,执行了callbak,但是字符串不能使用。
我正在使用 Robert Giesecke 的 DllExport for C#。 DelphiXE5 和 VS2012。
代码如下:
delphi:
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);
}
}
}
提前致谢。
您无需使用 out
进行此处的参数传递,并且调用约定与您的委托不匹配。委托的相关代码在C#端
public delegate void strCB(string s);
在Delphi这边
TStringCallback = procedure(str: PAnsiChar); stdcall;
我一直像您一样坚持使用 ANSI 字符串,但如果是我的代码,我个人会使用 Unicode。
代码现在可以根据 David 的建议运行。
不幸的是,我坚持使用 cdecl 调用约定和 delphi 端的 ansi 字符串。
Delphi:
unit Main;
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)
Button2: TButton;
Edit2: TEdit;
procedure Button2Click(Sender: TObject);
private
public
end;
TStringCallback = procedure(str:PAnsiChar); cdecl;
procedure strCallBack(fct: TStringCallback); cdecl; external 'csTest.dll';
var
Form2: TForm2;
implementation
{$R *.dfm}
//*************************************************************
//callback with string
procedure writeEdit2(str: PAnsiChar); cdecl;
begin
Form2.Edit2.Text := str;
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
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void strCB(String s);
[DllExport("strCallBack", CallingConvention = CallingConvention.Cdecl)]
public static void stringCallback(strCB fct)
{
String str = "hello from C#";
fct(str);
}
}
}
我正在尝试从 C# 导出函数并使用 delphi 应用程序调用该函数。 被调用的函数应该得到一个回调作为参数。此回调将字符串作为参数。 csharp_export_function(callbackfct(str))
我设法调用了一个 C# 函数,该函数写入一个字符串并在 delphi 中使用该字符串。 我还设法调用了一个带有回调作为参数的 C# 函数,并使用了这个回调。
但我无法获得以字符串作为参数的回调 运行。 在回调函数中使用字符串时,我在 Delphi 中遇到访问冲突异常。那里的字符串似乎是空的。 所以,执行了callbak,但是字符串不能使用。
我正在使用 Robert Giesecke 的 DllExport for C#。 DelphiXE5 和 VS2012。
代码如下:
delphi:
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);
}
}
}
提前致谢。
您无需使用 out
进行此处的参数传递,并且调用约定与您的委托不匹配。委托的相关代码在C#端
public delegate void strCB(string s);
在Delphi这边
TStringCallback = procedure(str: PAnsiChar); stdcall;
我一直像您一样坚持使用 ANSI 字符串,但如果是我的代码,我个人会使用 Unicode。
代码现在可以根据 David 的建议运行。 不幸的是,我坚持使用 cdecl 调用约定和 delphi 端的 ansi 字符串。
Delphi:
unit Main;
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)
Button2: TButton;
Edit2: TEdit;
procedure Button2Click(Sender: TObject);
private
public
end;
TStringCallback = procedure(str:PAnsiChar); cdecl;
procedure strCallBack(fct: TStringCallback); cdecl; external 'csTest.dll';
var
Form2: TForm2;
implementation
{$R *.dfm}
//*************************************************************
//callback with string
procedure writeEdit2(str: PAnsiChar); cdecl;
begin
Form2.Edit2.Text := str;
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
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void strCB(String s);
[DllExport("strCallBack", CallingConvention = CallingConvention.Cdecl)]
public static void stringCallback(strCB fct)
{
String str = "hello from C#";
fct(str);
}
}
}