如何使用Interop从C#传递十进制数到VB6

3

I have an interop c# class with a property:

decimal ImportoDocumento {  get; set; }

如果我尝试从VB6访问此属性,会收到错误:

编译器错误:函数或接口标记为受限制的,或函数使用VB不支持的自动化类型。

因此,我找到了这个部分解决方案:

decimal ImportoDocumento { [return: MarshalAs(UnmanagedType.Currency)] get; [param: MarshalAs(UnmanagedType.Currency)] set; }

但是货币仅支持最多4位小数的数字。我有6位小数的数字。

我该怎么办?

1个回答

2
错误信息是合适的,“decimal”不是有效的interop类型。它标准化非常差,大型芯片制造商如英特尔和AMD不愿意接触它。我已经记不起VB6了,但这篇MSDN文章很好地阐述了这一点:
“此时,Decimal数据类型只能在Variant中使用,也就是说,您不能声明一个变量为Decimal类型。但是,您可以使用CDec函数创建一个子类型为Decimal的Variant。”
通过将属性类型更改为“object”,您可以将属性声明为变体。我知道.NET Decimal类型实际上与VB6和VBA变体类型兼容,它被嵌入到oleauto.dll中,CLR和VB6和VBA运行时都使用它。修复方法:
[ComVisible(true)]
public interface IExample {
    object ImportoDocumento { get; set; }
}

[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class Example : IExample {
    private decimal documento;
    public object ImportoDocumento {
        get { return documento; }
        set { documento = Convert.ToDecimal(value, null); }
    }
}

请注意,您可以使用Convert.ToDecimal()方法的IFormatProvider参数进行调整。在VB6代码倾向于分配字符串时,这一点很重要,这种情况并不罕见。您还可以考虑CultureInfo.InvariantCulture.NumberFormat。

我试过了。从VB6中,如果我检查obj.ImportoDocumento的值,它可以正常工作。但是如果我尝试使用obj.ImportoDocumento = 1.2为其分配一个值,则会生成错误:运行时错误424:对象所需。 - Luca Romagnoli
哎呀,这是一个丑陋的VB6问题。它有两个属性设置器(put和putref),但C#只允许一个。尝试使用Set或Let关键字。 - Hans Passant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接