假设在delphi写一个dll,export这样一个函数:
在C#中如何调用这个函数呢?困难的地方在于OLEVariant如何处理,网上说处理成objec,先尝试一下这样:
protected void Button2_Click(object sender, EventArgs e)
{
object[] a;
int hResult;
int vLen;
object r;
object[] r2;
a = new object[2];
a.SetValue(3, 0);
a.SetValue(7, 1);
hResult = Test_OLEVariant("http://192.168.10.135:8081/ScreenEditor/DCSoapServerBroker.dll/soap/ISoapService",
a, out r);
结果产生一个异常:
无法封送处理“parameter #3”: 不能对返回类型、ByRef 参数、ArrayWithOffset 或从非托管传入托管的参数使用 AsAny。
再来试试:
结果还是产生异常:
无法封送处理“parameter #3”: 无效的托管/非托管类型组合(Object 类必须与 Interface、IUnknown、IDispatch、AsAny 或 Struct 成对出现)。
结果反复尝试,定义成这样就可以了:
protected void Button2_Click(object sender, EventArgs e)
{
object[] a;
int hResult;
int vLen;
object r;
object[] r2;
a = new object[2];
a.SetValue(3, 0);
a.SetValue(7, 1);
//r = new object();
hResult = Test_OLEVariant("http://192.168.10.135:8081/ScreenEditor/DCSoapServerBroker.dll/soap/ISoapService",
a, out r);
if (hResult == 0)
{
TextBox1.Text = r.ToString();
r2=(object[])(r);
TextBox1.Text = r2[0].ToString() + ":" + r2[1].ToString();
}
else
{
TextBox1.Text = hResult.ToString();
string sMsg;
sMsg = new string('/u0000', 512);
vLen = 512;
if (GetLastError(sMsg, ref vLen))
{
TextBox1.Text = sMsg;
}
}
}
即:传入的AParams定义成“ref object”,传出的AResult定义成“out object” 。
但是,如果返回的是VarArrayCreate([0,1000],varByte),在c#中就不能转换成object[],需要转换成byte[],这个比较奇怪,不是说anything is object吗?
但是如果函数在结果中返回Variant,却不会成功,会出现“PInvoke限制:无法返回变量”,如:
function Test_ReturnOLEVariant:OLEVariant;stdcall; begin Result:=VarArrayCreate([0,9],varByte); Result[2]:=2; end;
[DllImport("tmtsSoapStub.dll")] public static extern object Test_ReturnOLEVariant();