我尝试了以下方法,但我得到了错误。“外部组件引发异常。”
这是我第一次用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/"));
}
}
}发布于 2013-05-20 01:59:20
您不能从C#调用该函数。这是因为你不能使用Delphi string进行互操作。您可以对从托管传递到非托管的字符串使用PAnsiChar,但在另一个方向上,它更复杂。您需要在调用方分配内存,或者使用共享堆。我更喜欢后一种方法,这是使用COM BSTR最容易完成的方法。这是德尔福的WideString。
正如discussed before一样,您不能使用WideString作为互操作的返回值,因为Delphi使用与MS工具不同的ABI来返回值。
Delphi代码需要如下所示:
procedure HTTPGET(URL: PAnsiChar; out result: WideString); stdcall;在C#端,你可以这样写它:
[DllImport("project1.dll")]
public static extern void HTTPGET(
string URL,
[MarshalAs(UnmanagedType.BStr)]
out string result
); 如果您希望使用Unicode作为URL,则使用PWideChar和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
); 发布于 2013-05-20 01:42:57
不要使用string类型:字符串需要内存管理,而C#和Delphi模块显然使用不同的内存管理器(更不用说C#传递char*,而Delphi期望String)。尝试在DLL中将location类型更改为PChar,并将结果类型更改为PChar (缓冲区应显式分配)或其他类型,但不是string。
发布于 2013-05-20 01:48:46
我记得,你不能用C#编组delphi字符串...您必须使用PChar的变通方法并自己管理内存,或者使用此处最后一个答案中提供的变通方法:
https://stackoverflow.com/questions/16637476
复制相似问题