Reputation:
How can i use this dll function in c#? I tried the following but i get error. "External component has thrown an exception."
First time i am doing this PInvoke stuff with C# and Delphi.
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/"));
}
}
}
Upvotes: 1
Views: 1199
Reputation: 375
Try Unmanaged Exports for c# by Robert Giesecke
https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports
we are using encrypting engine from c# in Delphi App due compatibility with php and works well (so, the mentioned strings problem do not exists).
our earlier solution (worse) : register c# dll as com component and use it. with above solution output library have to be placed in exe directory and without registration works well :)
Upvotes: -1
Reputation: 613441
You cannot call that function from C#. That's because you cannot use Delphi string
for interop. You can use PAnsiChar
for strings passed from managed to unmanaged, but in the other direction it's more complex. You'd need to allocate the memory at the caller, or use a shared heap. I prefer the latter approach which is easiest done with the COM BSTR
. This is WideString
in Delphi.
As has been discussed before, you cannot use WideString
as a return value for interop, since Delphi uses a different ABI from MS tools for return values.
The Delphi code needs to look like this:
procedure HTTPGET(URL: PAnsiChar; out result: WideString); stdcall;
On the C# side you write it like this:
[DllImport("project1.dll")]
public static extern void HTTPGET(
string URL,
[MarshalAs(UnmanagedType.BStr)]
out string result
);
If you want Unicode for the URL then use PWideChar
and CharSet.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
);
Upvotes: 7
Reputation: 2930
As i remember, you can't marshall delphi strings with C#... you have to use a workaround with PChar and manage the memory yourself, or use something like the workaround provided in the last answer here:
Using Delphi's stuct arrays and strings in C#
Upvotes: -1
Reputation: 11058
Do not use string
type: strings require memory management, and C# and Delphi modules obviously use different memory managers (leave alone that C# passes char*
and Delphi expects String
). Try changing location
type to PChar in your DLL, and also change your result type so it's either PChar (the buffer should be allocated explicitly) or something else, but not string
.
Upvotes: 0