PInvoke和Delphi

1 c# delphi pinvoke

我怎样才能在c#中使用这个dll函数?我尝试了以下但我得到错误."外部组件引发的异常."

我第一次用C#和Delphi做这个PInvoke的东西.

function HTTPGET(location:string):string; stdcall;
var
HTTP:TIdHttp;
begin
  HTTP := TidHttp.Create(nil);
  try
    result := HTTP.Get(location);
  finally
  FreeAndNil(HTTP);
  end;
end;


exports
  HTTPGET;

begin
end.


namespace Test
{
    class Program
    {
        [DllImport("project1.dll")]
        public static extern string HTTPGET(string location);

        static void Main(string[] args)
        {
           Console.WriteLine(HTTPGET("http://www.reuters.com/"));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 7

你无法从C#调用该函数.那是因为你不能使用Delphi string进行互操作.您可以使用PAnsiChar从托管传递到非托管的字符串,但在另一个方向上它更复杂.您需要在调用者处分配内存,或使用共享堆.我更喜欢后一种方法,这种方法最容易用COM完成BSTR.这是WideString在Delphi中.

正如已经讨论过,你不能用WideString作为互操作的返回值,因为德尔福从MS工具使用不同的ABI的返回值.

Delphi代码需要如下所示:

procedure HTTPGET(URL: PAnsiChar; out result: WideString); stdcall;
Run Code Online (Sandbox Code Playgroud)

在C#端你就像这样写:

[DllImport("project1.dll")] 
public static extern void HTTPGET(
    string URL,
    [MarshalAs(UnmanagedType.BStr)]
    out string result
);     
Run Code Online (Sandbox Code Playgroud)

如果您想要URL的Unicode,请使用PWideCharCharSet.Unicode.

procedure HTTPGET(URL: PWideChar; out result: WideString); stdcall;
....
[DllImport("project1.dll", CharSet=CharSet.Unicode)] 
public static extern void HTTPGET(
    string URL,
    [MarshalAs(UnmanagedType.BStr)]
    out string result
);     
Run Code Online (Sandbox Code Playgroud)

  • @AJ.它在Delphi代码中分配,并在C#代码中解除分配.您根本不需要担心它,因为框架会为您完成.因为它是一个`BSTR`,所以内存来自共享的COM堆,这就是你可以在不同模块中分配和释放的原因. (2认同)