System.ArgumentException:VariantWrappers无法存储在Variants中

时间:2009-07-16 14:05:18

标签: c# com

我有一个COM对象,它具有以下类型def(如OleView所示):

[id(0x60030010)]
HRESULT Calc(
                [in] BSTR calculation_type, 
                [in] short pricing_model, 
                [in] BSTR option_type, 
                [in] double strike, 
                [in] double spot, 
                [in] double P1, 
                [in] double days, 
                [in] double Volatility, 
                [in] double risk_free_rate, 
                [in] double P2, 
                [in] VARIANT NotUsed, 
                [in] double P3, 
                [in] short binomial_steps, 
                [in, out] VARIANT* dividends, 
                [in, out] VARIANT* days_to_ex_dates, 
                [in] short dividend_count, 
                [in] BSTR dividend_type, 
                [out, retval] VARIANT* );

COM interop包装器生成以下方法签名:

[return: MarshalAs(UnmanagedType.Struct)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0x60030010)]
public virtual extern object Calc([In, MarshalAs(UnmanagedType.BStr)] string calculation_type, [In] short pricing_model, [In, MarshalAs(UnmanagedType.BStr)] string option_type, [In] double strike, [In] double spot, [In] double P1, [In] double days, [In] double Volatility, [In] double risk_free_rate, [In] double P2, [In, MarshalAs(UnmanagedType.Struct)] object NotUsed, [In] double P3, [In] short binomial_steps, **[In, Out, MarshalAs(UnmanagedType.Struct)] ref object dividends, [In, Out, MarshalAs(UnmanagedType.Struct)] ref object days_to_ex_dates**, [In] short dividend_count, [In, MarshalAs(UnmanagedType.BStr)] string dividend_type);

我试图通过以下方式调用此方法,每次都有各种异常:

object dividends = null;
object daysToExDates = null;
double price = (double)comobj.Calc("P", 1, "C", 2.5, 2.59, 1, 8, 1, 0.01, 0, 0, 0, 50, ref dividends, ref dividends, 0, "C");

System.Runtime.InteropServices.COMException:类型不匹配

object dividends = 0.0d;
object daysToExDates = 0.0d;
double price = (double)comobj.Calc("P", 1, "C", 2.5, 2.59, 1, 8, 1, 0.01, 0, 0, 0, 50, ref dividends, ref dividends, 0, "C");

System.Runtime.InteropServices.COMException:类型不匹配

object dividends = new double[1];
object daysToExDates = new double[1];
double price = (double)comobj.Calc("P", 1, "C", 2.5, 2.59, 1, 8, 1, 0.01, 0, 0, 0, 50, ref dividends, ref dividends, 0, "C");

System.IndexOutOfRangeException:下标超出范围

object dividends = new double[100];
object daysToExDates = new double[100];
double price = (double)comobj.Calc("P", 1, "C", 2.5, 2.59, 1, 8, 1, 0.01, 0, 0, 0, 50, ref dividends, ref dividends, 0, "C");

System.Runtime.InteropServices.COMException:对象变量或With block变量未设置

object dividends = Array.CreateInstance(typeof(double), new int[] { 1 }, new int[] { 1 });
object daysToExDates = Array.CreateInstance(typeof(double), new int[] { 1 }, new int[] { 1 });
double price = (double)comobj.Calc("P", 1, "C", 2.5, 2.59, 1, 8, 1, 0.01, 0, 0, 0, 50, ref dividends, ref dividends, 0, "C");

System.Runtime.InteropServices.COMException:对象变量或With block变量未设置

object dividends = new VariantWrapper(0.0d);
object daysToExDates = new VariantWrapper(0.0d);
double price = (double)comobj.Calc("P", 1, "C", 2.5, 2.59, 1, 8, 1, 0.01, 0, 0, 0, 50, ref dividends, ref dividends, 0, "C");

System.ArgumentException:VariantWrappers无法存储在Variants中。

object dividends = new VariantWrapper(new double[1]);
object daysToExDates = new VariantWrapper(new double[1]);
double price = (double)comobj.Calc("P", 1, "C", 2.5, 2.59, 1, 8, 1, 0.01, 0, 0, 0, 50, ref dividends, ref dividends, 0, "C");

System.ArgumentException:VariantWrappers无法存储在Variants中。

最令人沮丧的是,以下VBA块工作正常:

Dim div() As Double
ReDim div(1 To 1)
Dim price As Double
price = comobj.Calc("P", 1, "C", 2.5, 2.59, 0, 8, 1, 0.01, 0, 0, 0, 50, div, div, 0, "C")

为什么VariantWrapper不起作用?有什么想法吗?

1 个答案:

答案 0 :(得分:0)

VariantWrapper用于创建包含对其他VARIANT的引用(指针)的VARIANT。你需要的是一个VARIANT,它将通过引用传递,包含一个double。

请尝试以下代码段。

double dividends = 0.0d;
double daysToExDates = 0.0d;

// Create Boxed Copies to be referenced
Object oTmpDividends = dividends;
Object oTmpDaysToExDates = daysToExDates;

double price = (double)comobj.Calc("P", 1, "C", 2.5, 2.59, 1, 8, 1, 0.01, 
    0, 0, 0, 50, ref oTmpDividends, ref oTmpDaysToExDates, 0, "C");

// Unbox the copies
dividends = (double)oTmpDividends;
daysToExDates = (double)oTmpDaysToExDates;

这与VB.NET的功能基本相同,但在这种情况下,VB.NET会为您处理对象和对象之间的区别。