1

一个朋友问我关于用 C# 为一个 delphi 应用程序编写一个 dll。他想使用这个函数 decleration 与它通信:

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.
4

2 回答 2

4

你正在尝试的是不可能的。您不能在 C# 中实现 Delphi 表单。您发布的代码将 DLL 函数返回的指针视为 Delphi 形式。唯一可以实现 Delphi 表单的是 Delphi 编译的代码。

更重要的是,如果 DLL 是在 Delphi 中实现的,您的代码甚至无效。这是因为TForm宿主可执行文件中的TForm类与 DLL 中的类不同。为了使用 Delphi DLL 执行您尝试执行的操作,您需要跨模块边界传递接口。

最重要的是,您当前对该附加架构的设计永远无法工作。您需要立即回到绘图板并重新开始。

于 2013-05-13T16:17:50.643 回答
1

或许,您可以通过对 Delphi 中的调用例程稍作改动来实现它。

如果您要使用 David 提到的UnmanagedExports(作为 Nuget 包提供),您可以获得 OpenAddonFile 调用以返回接口而不是表单。该接口可以实现 ShowModal 和 Position。
CloseAddonFile 可以正常返回适当的值。不管它是控制台应用程序还是其他任何形式,只要您可以在其上调用 ShowModal 即可。

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

于 2013-05-14T10:18:03.380 回答