. net vb6包装器属性与参数



我需要为vb6应用程序编写一个c#包装器。我总是得到错误450(错误的参数或属性分配是无效的。)这是我的VB代码

Dim DBEngine As New DBEngineNet
Set mDbEProp = DBEngine.Properties("Version") ' <-- ERROR

这段代码正常工作,所以问题是属性

的参数
Dim DBEngine As New DBEngineNet
Set mDbEProps = DBEngine.Properties
Set mDbEProp = mDbEProps("Version")  '<-- Working. Results 1.0

这是我的COM-Visible c#代码。它使用旧的VB6-MotorApp的互操作接口。

[ComVisible(true)]
public class DBEngineNet : VB6MotorApp.DBEngine
{
    public VB6MotorApp.Properties Properties
    {
        // [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_SAFEARRAY)] Maybe something like this???
        get
        {
            return new PropertiesNet
                {
                    new PropertyNet{Name="Version", Value="1.0"}
                };
        }
    }

属性对象:

[ComVisible(true)]
public class PropertiesNet : VB6MotorApp.Properties, IList<PropertyNet>
{
    List<PropertyNet> _properties = new List<PropertyNet>();
    public VB6MotorApp.Property this[object Item]
    {
        get
        {
            return _properties.FirstOrDefault(p => p.Name == Item.ToString());
        }
    }
}

任何想法?

您需要的基本诊断工具是OleView.exe,从Visual Studio命令提示符运行它。使用它的File + View typelib命令查看类型库并对它们进行比较。首先是你原来的VB6实现,这样你就有了一个基线,接下来是你的。net版本的类型库。

你现在做的方式不可避免地会有很大的不同,你暴露了太多的类实现细节。整个系统。对象方法以及IList<>实现方法将是可见的。Boilerplate是声明一个[ComVisible(true)]接口(VB6喜欢他们的名字以一个_下划线开头),并通过给它[ClassInterface(ClassInterfaceType.None)]属性来隐藏类的实现。你已经有了接口,所以只需要属性。

在OleView.exe输出中首先要查找的是DBEngineNet的[dispid]属性。属性的属性。它不像默认属性,这就是为什么你必须在VB6代码中显式地获取属性值。默认属性为dispid(0)。你可以在。net代码中通过给它[DispId(0)]属性来强制值。

你还想看看原来的类型库"VB6MotorApp"。"属性"看起来不对。那是一个协类名,而不是接口名。你应该使用VB6MotorApp._Properties的非零几率。VB6MotorApp._DBEngine.

并查看coclasses中的哪些接口具有[default]属性。应该是VB6接口。如果你的VB6代码片段像发布的那样工作,可能不是问题。

最新更新