简体   繁体   English

带参数的.NET vb6包装器属性

[英].NET vb6 wrapper property with parameter

i need to write ac# wrapper for a vb6 application. 我需要为vb6应用程序编写ac#包装程序。 I always get error 450 ( Wrong number of arguments or property assignment was not valid.) This is my VB Code 我总是收到错误450(错误的参数数量或属性分配无效。)这是我的VB代码

Dim DBEngine As New DBEngineNet

Set mDbEProp = DBEngine.Properties("Version") ' <-- ERROR

This code is working, so the problem is the parameter of the property 该代码有效,所以问题出在属性的参数上

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

Here is my COM-Visible C#-Code. 这是我的COM可见C#代码。 It uses the Interop-Interfaces of the old VB6-MotorApp. 它使用旧版VB6-MotorApp的Interop-Interfaces。

[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"}
                };
        }
    }

Here is the Properties-Object: 这是Properties-Object:

[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());
        }
    }
}

Any ideas? 有任何想法吗?

The basic diagnostic tool you need here is OleView.exe, run it from the Visual Studio Command Prompt. 这里需要的基本诊断工具是OleView.exe,可以从Visual Studio命令提示符运行它。 Use its File + View typelib command to look at the type libraries and compare them. 使用其File + View typelib命令查看类型库并进行比较。 First on your original VB6 implementation so you have a base-line, next on the type library for your .NET version. 首先,在原始VB6实现上,有了一个基线,然后是.NET版本的类型库。

There are inevitably going to be major difference the way you are doing it now, you are exposing too many details of the class implementation. 现在的方式不可避免地会有很大的不同,因为您暴露了太多的类实现细节。 All of the System.Object methods as well as the IList<> implementation methods are going to be visible. 所有System.Object方法以及IList <>实现方法都将可见。 Boilerplate is to declare a [ComVisible(true)] interface (VB6 likes their name to start with an _underscore) and hide the class implementation by giving it the [ClassInterface(ClassInterfaceType.None)] attribute. Boilerplate声明了一个[ComVisible(true)]接口(VB6喜欢它们的名称以_underscore开头),并通过为它提供[ClassInterface(ClassInterfaceType.None)]属性来隐藏类实现。 You already have the interface so only the attribute should be necessary. 您已经有了接口,因此仅需要该属性。

What you want to look for first in the OleView.exe output is the [dispid] attribute for the DBEngineNet.Properties property. 您首先要在OleView.exe输出中查找的是DBEngineNet.Properties属性的[dispid]属性。 It doesn't act like the default property which is why you have to obtain the property value explicitly in your VB6 code. 它的行为不像默认属性,这就是为什么您必须在VB6代码中显式获取属性值的原因。 The default property has dispid(0). 默认属性为dispid(0)。 You force the value in .NET code by giving it the [DispId(0)] attribute. 通过为[NET ID]属性赋予[DispId(0)]属性,可以强制该值。

You also want to look at the original type library, "VB6MotorApp.Properties" looks wrong. 您还想查看原始类型库,“ VB6MotorApp.Properties”看起来不对。 That's a coclass name, not an interface name. 那是一个coclass名,而不是一个接口名。 Non-zero odds that you should be using VB6MotorApp._Properties. 您应该使用VB6MotorApp._Properties的非零赔率。 Same for VB6MotorApp._DBEngine. 与VB6MotorApp._DBEngine相同。

And look at which interfaces in the coclasses have the [default] attribute. 并查看协同类中的哪些接口具有[default]属性。 It should be the VB6 interfaces. 它应该是VB6接口。 Probably not an issue if your VB6 snippets work as posted. 如果您的VB6片段按发布方式工作,则可能不是问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM