为Delphi应用程序编写.net (c#) dll

本文关键字:dll net Delphi 应用程序 | 更新日期: 2023-09-27 18:13:15

一个朋友问我如何用c#为delphi应用程序编写一个dll。他想用下面的函数声明与dll进行通信:

function OpenAddOnFile(const mafCode: PWideChar; const mafFilePath: PWideChar;
                   const mafVersion: PWideChar): Pointer; stdcall;

我遇到的问题是把它翻译成c#。PWideChar不可用等…我已经试过了:

public Pointer OpenAddOnFile(
    [MarshalAs(UnmanagedType.LPWStr)]string mafcode,     
    [MarshalAs(UnmanagedType.LPWStr)]string maffilepath,  
    [MarshalAs(UnmanagedType.LPWStr)]string mafversion
)

但是它现在不工作:)

进一步,我如何在c#中返回一个指针到我的表单?

有人能帮我一下吗?提前感谢!

编辑:'

他给了我这个额外的代码:我向他询问函数调用,他给了我这个信息:

unit unAddOn;
interface
uses
   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
   System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
   Vcl.ComCtrls;
function LoadAddOnFile(aPath: String; aVersion: String; var aFilePath: String;
                       var aCode: String): Boolean;
const
    AddOnExt: String = '.maf';
implementation
function LoadAddOnFile(aPath: String; aVersion: String; var aFilePath: String;
                   var aCode: String): Boolean;
type
   TOpenAddOnFile = function(const mafCode: PWideChar; const mafFilePath: PWideChar;
                        const mafVersion: PWideChar): Pointer; stdcall;
   TCloseAddOnFile = procedure(var mafCode: PWideChar; var mafFilePath: PWideChar;
                          var mafQuitPopUp: PWideChar); stdcall;
var
   CloseAddOnFile: TCloseAddOnFile;
   OpenAddOnFile: TOpenAddOnFile;
   AddOnMainForm: TForm;
   AddOnHandle: THandle;
   mafQuitPopUp: PWideChar;
   mafFilePath: PWideChar;
   mafVersion: PWideChar;
   mafCode: PWideChar;
begin
   Result := True;
   mafQuitPopUp := PWideChar(EmptyStr);
   mafFilePath  := PWideChar(aFilePath);
   mafCode      := PWideChar(aCode);
   mafVersion   := PWideChar(aVersion);
   try
   AddOnHandle := LoadLibrary(PWideChar(aPath));
if (AddOnHandle <> 0) then
begin
  @OpenAddOnFile  := GetProcAddress(AddOnHandle, 'OpenAddOnFile');
  @CloseAddOnFile := GetProcAddress(AddOnHandle, 'CloseAddOnFile');
  if (@OpenAddOnFile <> nil) then
  begin
    AddOnMainForm := OpenAddOnFile(mafCode, mafFilePath, mafVersion);
    AddOnMainForm.Position := poScreenCenter;
    AddOnMainForm.ShowModal;
    if (@CloseAddOnFile <> nil) then
    begin
      CloseAddOnFile(mafCode, mafFilePath, mafQuitPopUp);
    end;
    FreeAndNil(AddOnMainForm);
    Application.ProcessMessages;
  end;
end;
if not (mafQuitPopUp = PWideChar(EmptyStr)) then
begin
  ShowMessage(mafQuitPopUp);
end;
aFilePath := String(mafFilePath);
aCode := String(mafCode);
except
Result := False;
end;
end;
end.

为Delphi应用程序编写.net (c#) dll

你的企图是不可能的。你不能在c#中实现Delphi表单。您发布的代码将DLL函数返回的指针视为Delphi窗体。唯一可以实现Delphi表单的是Delphi编译的代码。

更重要的是,如果DLL是在Delphi中实现的,你的代码甚至是无效的。这是因为主机可执行文件中的TForm类与DLL中的TForm类不同。为了用Delphi DLL做你想做的事情,你需要跨模块边界传递接口。

底线是,您当前的附加架构设计永远无法工作。你需要回到画板上重新开始。

您也许可以通过对Delphi中的调用例程进行微小更改来略微不同地实现它。

如果要使用David提到的UnmanagedExports(作为Nuget包可用),则可以使用OpenAddonFile调用返回接口而不是表单。接口可以实现ShowModal和Position。
CloseAddonFile可以正常返回一个适当的值。不管它是一个窗体,控制台应用程序还是其他任何东西,只要你能在它上面调用ShowModal就无所谓了。

我发现UnmanagedExports非常好,只要你记得只从方法返回int/void类型,任何字符串都作为var/out参数返回。