首先,CLSCompliant
属性与COM 没有任何关系。这是为了公共语言运行时合规性。
OLE 自动化规范列出了自动化兼容的类型。
您的 C# 类,如果编译为 32 位程序集并使用 RegAsm 注册,则公开以下 COM 接口:
[
odl,
uuid(AFA13243-F593-3B28-A4D3-4E4138AA1F22),
hidden,
dual,
nonextensible,
oleautomation,
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "SampleNSpace.AnyClass")
]
interface _AnyClass : IDispatch {
[id(00000000), propget,
custom(54FC8F55-38DE-4703-9C4E-250351302B1C, 1)]
HRESULT ToString([out, retval] BSTR* pRetVal);
[id(0x60020001)]
HRESULT Equals(
[in] VARIANT obj,
[out, retval] VARIANT_BOOL* pRetVal);
[id(0x60020002)]
HRESULT GetHashCode([out, retval] long* pRetVal);
[id(0x60020003)]
HRESULT GetType([out, retval] _Type** pRetVal);
[id(0x60020004)]
HRESULT GetAnyInt([out, retval] long* pRetVal);
[id(0x60020005)]
HRESULT GetAnyLong([out, retval] int64* pRetVal);
[id(0x60020006)]
HRESULT GetAnyDecimal([out, retval] wchar_t* pRetVal);
[id(0x60020007)]
HRESULT GetAnyDouble([out, retval] double* pRetVal);
};
我不确定是否int64
被认为是自动化兼容的(它不包含在我上面提到的列表中),但double
肯定是自动化兼容的。因此,我怀疑这可能是 VFP 方面的问题。要解决此问题,您可以尝试更改 C# 类的定义以object
用于这些类型。还要注意如何MarshalAs(UnmanagedType.Currency)
用于编组decimal
为 OLECURRENCY
类型。
[assembly: CLSCompliant(true)]
namespace SampleNSpace
{
[ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("111B0014-EB08-4093-A818-1D11EB4C489D")]
public class AnyClass
{
public int GetAnyInt() { return int.MaxValue; }
[return: MarshalAs(UnmanagedType.Struct)]
public object GetAnyLong() { return long.MaxValue; }
[return: MarshalAs(UnmanagedType.Currency)]
public decimal GetAnyDecimal() { return decimal.MaxValue; }
[return: MarshalAs(UnmanagedType.Struct)]
public object GetAnyDouble() { return double.MaxValue; }
}
}
这会产生以下 COM 接口VARIANT
,我希望它可以与 VFP 一起使用:
[
odl,
uuid(671A483A-5327-391A-AF09-4D734F9DFDCF),
hidden,
dual,
nonextensible,
oleautomation,
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "SampleNSpace.AnyClass")
]
interface _AnyClass : IDispatch {
[id(00000000), propget,
custom(54FC8F55-38DE-4703-9C4E-250351302B1C, 1)]
HRESULT ToString([out, retval] BSTR* pRetVal);
[id(0x60020001)]
HRESULT Equals(
[in] VARIANT obj,
[out, retval] VARIANT_BOOL* pRetVal);
[id(0x60020002)]
HRESULT GetHashCode([out, retval] long* pRetVal);
[id(0x60020003)]
HRESULT GetType([out, retval] _Type** pRetVal);
[id(0x60020004)]
HRESULT GetAnyInt([out, retval] long* pRetVal);
[id(0x60020005)]
HRESULT GetAnyLong([out, retval] VARIANT* pRetVal);
[id(0x60020006)]
HRESULT GetAnyDecimal([out, retval] CURRENCY* pRetVal);
[id(0x60020007)]
HRESULT GetAnyDouble([out, retval] VARIANT* pRetVal);
};