一位朋友问我在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.
答案 0 :(得分:4)
你所尝试的是不可能的。您无法在C#中实现Delphi表单。您发布的代码将DLL函数返回的指针视为Delphi表单。唯一可以实现Delphi表单的是Delphi编译的代码。
此外,如果DLL是在Delphi中实现的,那么您的代码甚至无效。那是因为主机可执行文件中的TForm
类与DLL中的TForm
类不同。为了使用Delphi DLL执行您尝试执行的操作,您需要跨模块边界传递接口。
最重要的是,您对此附加架构的当前设计永远不会起作用。你需要回到绘图板然后重新开始。
答案 1 :(得分:1)
或许,您可以通过对Delphi中调用例程的微小更改来稍微改变它。
如果您使用David提到的UnmanagedExports(可用作Nuget包),您可以通过OpenAddonFile调用返回界面而不是表单。界面可以实现ShowModal和Position。左CloseAddonFile可以正常返回一个合适的值。然后,只要你可以在其上调用ShowModal,它是否构成一个控制台应用程序或其他任何东西并不重要。
我发现UnmanagedExports非常好,只要你记得只返回方法中的int / void类型,任何字符串都作为var / out参数返回。