AutoCAD 的 C# 插件具有“未实现”但仍可构建的接口成员?

问题描述 投票:0回答:1

我正在尝试将属性添加到 AutoCAD 中的对象属性管理器 (OPM)。我正在关注这些文章第 1 部分 第 2 部分

我还从 Github 分叉了 this 项目,该项目遵循这些文章。

将所有设置设置为适用于 AutoCAD 2024 和 ObjectARX 2024 后,C++(我非常不熟悉)将进行编译和构建。

C# 部分也可以构建。但有些错误让人相信它不应该

Errors in the C# plugin project

Error for GetDisplayName method

[
    Guid("F60AE3DA-0373-4d24-82D2-B2646517ABCB"),
    ProgId("OPMNetSample.CustomProperty.1"),

    // No class interface is generated for this class and
    // no interface is marked as the default.
    // Users are expected to expose functionality through
    // interfaces that will be explicitly exposed by the object
    // This means the object can only expose interfaces we define

    ClassInterface(ClassInterfaceType.None),
    // Set the default COM interface that will be used for
    // Automation. Languages like: C#, C++ and VB allow to 
    //query for interface's we're interested in but Automation 
    // only aware languages like javascript do not allow to 
    // query interface(s) and create only the default one

    ComDefaultInterface(typeof(IDynamicProperty2)),
    ComVisible(true)
]
public class CustomProp : IDynamicProperty2 {
    private IDynamicPropertyNotify2 m_pSink =null;

   // Unique property ID
    void IDynamicProperty2.GetGUID(out Guid propGUID)
    {
        propGUID = new Guid("F60AE3DA-0373-4d24-82D2-B2646517ABCB");
    }

    // Property display nameD
    void IDynamicProperty2.GetDisplayName(out string szName)
    {
        szName = "My integer property";
    }

    // Show/Hide property in the OPM, for this object instance
    void IDynamicProperty2.IsPropertyEnabled(object pUnk, out int bEnabled)
    {
        bEnabled = 1;
    }

    // Is property showing but disabled
    void IDynamicProperty2.IsPropertyReadOnly(out int bReadonly)
    {
        bReadonly = 0;
    }

    // Get the property description string
    void IDynamicProperty2.GetDescription(out string szName)
    {
        szName = "This property is an integer";
    }

    // OPM will typically display these in an edit field
    // optional: meta data representing property type name,
    // ex. ACAD_ANGLE
    void IDynamicProperty2.GetCurrentValueName(out string szName)
    {
        throw new System.NotImplementedException();
    }

    // What is the property type, ex. VT_R8
    void IDynamicProperty2.GetCurrentValueType(out ushort varType)
    {
        // The Property Inspector supports the following data
        // types for dynamic properties:
        // VT_I2, VT_I4, VT_R4, VT_R8,VT_BSTR, VT_BOOL
        // and VT_USERDEFINED. 

        varType = 3; // VT_I4
    }

    // Get the property value, passes the specific object
    // we need the property value for.
    void IDynamicProperty2.GetCurrentValueData(object pUnk, ref object pVarData)
    {
        // TODO: Get the value and return it to AutoCAD

        // Because we said the value type was a 32b int (VT_I4)
        pVarData = (int)4;
    }

    // Set the property value, passes the specific object we
    // want to set the property value for
    void IDynamicProperty2.SetCurrentValueData(object pUnk, object varData)
    {
        // TODO: Save the value returned to you

        // Because we said the value type was a 32b int (VT_I4)
        int myVal = (int)varData;
    }

    // OPM passes its implementation of IDynamicPropertyNotify, you
    // cache it and call it to inform OPM your property has changed
    void IDynamicProperty2.Connect(object pSink)
    {
        m_pSink = (IDynamicPropertyNotify2)pSink;
    }

    void IDynamicProperty2.Disconnect()
    {
        m_pSink = null;
    }

}

IDynamicProperty2
来自 C++ 项目,该项目负责将其提供给 .NET

//- IDynamicProperty2.h

#pragma once

using namespace System;
using namespace System::Runtime;
using namespace System::Runtime::InteropServices;
using namespace Autodesk::AutoCAD::Runtime;
using namespace Autodesk::AutoCAD::DatabaseServices;

#include "dynprops.h"

namespace Autodesk
{
  namespace AutoCAD
  {
    namespace Windows
    {
      namespace OPM
      {
        [InteropServices::Guid("9CAF41C2-CA86-4ffb-B05A-AC43C424D076")]
        [InteropServices::InterfaceTypeAttribute(InteropServices::ComInterfaceType::InterfaceIsIUnknown)]
        [InteropServices::ComVisible(true)]
        public interface class IDynamicProperty2
        {
          void GetGUID(
            [InteropServices::Out] System::Guid% propGUID
          );
          void GetDisplayName(
            [InteropServices::Out,
             InteropServices::MarshalAs(
              InteropServices::UnmanagedType::BStr
             )
            ] interior_ptr<System::String^> name);
          void IsPropertyEnabled(
            [InteropServices::In,
             InteropServices::MarshalAs(
               InteropServices::UnmanagedType::IUnknown
             )
            ] Object^ pUnk,
            [InteropServices::Out] System::Int32% bEnabled
          );
          void IsPropertyReadOnly(
            [InteropServices::Out] System::Int32% bReadonly
          );
          void GetDescription(
            [InteropServices::Out,
             InteropServices::MarshalAs(
               InteropServices::UnmanagedType::BStr
             )
            ] interior_ptr<System::String^> description
          );
          void GetCurrentValueName(
            [InteropServices::Out,
             InteropServices::MarshalAs(
               InteropServices::UnmanagedType::BStr
             )
            ] interior_ptr<System::String^> name
          );
          void GetCurrentValueType(
            [InteropServices::Out] ushort% pVarType
          );
          void GetCurrentValueData(
            [InteropServices::In,
             InteropServices::MarshalAs(
               InteropServices::UnmanagedType::IUnknown
             )
            ] Object^ pUnk,
            [InteropServices::In,
             InteropServices::Out,
             InteropServices::MarshalAs(
               InteropServices::UnmanagedType::Struct
             )
            ] interior_ptr<Object^> varData
          );
          void SetCurrentValueData(
            [InteropServices::In,
             InteropServices::MarshalAs(
               InteropServices::UnmanagedType::IUnknown
             )
            ] Object^ pUnk,
            [InteropServices::In,
             InteropServices::MarshalAs(
               InteropServices::UnmanagedType::Struct
             )
            ] Object^ varData
          );
          void Connect(
            [InteropServices::In,
             InteropServices::MarshalAs(
               /*IDynamicPropertyNotify2*/
               InteropServices::UnmanagedType::IUnknown
             )
            ] Object^ pSink
          );
          void Disconnect();
        };
        [InteropServices::Guid(
           "975112B5-5403-4197-AFB8-90C6CA73B9E1"
        )]
        [InteropServices::InterfaceTypeAttribute(
           InteropServices::ComInterfaceType::InterfaceIsIUnknown
        )]
        [InteropServices::ComVisible(true)]
        public interface class IDynamicPropertyNotify2
        {
          void OnChanged(
            [InteropServices::In,
             InteropServices::MarshalAs(
               InteropServices::UnmanagedType::IUnknown
             )
            ] Object^ pDynamicProperty
          );
          void GetCurrentSelectionSet(
            [InteropServices::In,
             InteropServices::Out,
             InteropServices::MarshalAs(
               InteropServices::UnmanagedType::Struct
             )
            ] interior_ptr<Object^> pSelection
          );
        };
      }
    }
  }
}

这是

IDynamicProperty2
的声明,它是 ObjectARX API 的一部分,位于
dynprops.h

//--------------------------
// IDynamicProperty2 interface
// Implement this class to create dynamic properties for the PropertyPalette
// it defines the base set of property attributes as well as
// the name/type/data tuples. 
//--------------------------
// {9CAF41C2-CA86-4ffb-B05A-AC43C424D076}
DEFINE_GUID(IID_IDynamicProperty2, 0x9caf41c2, 0xca86, 0x4ffb, 0xb0, 0x5a, 0xac, 0x43, 0xc4, 0x24, 0xd0, 0x76);

interface DECLSPEC_UUID("9CAF41C2-CA86-4ffb-B05A-AC43C424D076")
IDynamicProperty2 : public IUnknown
{
    BEGIN_INTERFACE
    // *** IUnknown methods ****

    STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;
    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
    STDMETHOD_(ULONG, Release)(THIS) PURE;

    // *** IDynamicProperty2 methods ***
    //Unique property ID
    STDMETHOD(GetGUID)(THIS_ /*[out]*/GUID* propGUID) PURE;
    // Property display name
    STDMETHOD(GetDisplayName)(THIS_ /*[out]*/BSTR* bstrName) PURE;
    // Show/Hide property in the OPM, for this object instance 
    STDMETHOD(IsPropertyEnabled)(THIS_ /*[in]*/IUnknown *pUnk,
                                      /*[out]*/BOOL* pbEnabled) PURE;
    // Is property showing but disabled
    STDMETHOD(IsPropertyReadOnly)(THIS_ /*[out]*/BOOL* pbReadonly) PURE;
    // Get the property description string
    STDMETHOD(GetDescription)(THIS_ /*[out]*/BSTR* bstrName) PURE;
    
    // *** Basic property value information ***
    // OPM will typically display these in an edit field
    
    // optional: meta data representing property type name, ex. ACAD_ANGLE
    STDMETHOD(GetCurrentValueName)(THIS_ /*[out]*/BSTR* pbstrName) PURE;
    // What is the property type, ex. VT_R8
    STDMETHOD(GetCurrentValueType)(THIS_ /*[out]*/VARTYPE* pVarType) PURE;
    // Get the property value, passes the specific object we need the property
    // value for.
    STDMETHOD(GetCurrentValueData)(THIS_ /*in*/IUnknown *pUnk, 
                                      /*[out]*/VARIANT* pvarData) PURE;
    // Set the property value, passes the specific object we want to set the 
    // property value for
    STDMETHOD(SetCurrentValueData)(THIS_ /*[in]*/IUnknown *pUnk, 
                                         /*[in]*/const VARIANT varData) PURE;

    //*** Notifications ***
    //OPM passes its implementation of IDynamicPropertyNotify, you
    //cache it and call it to inform OPM your property has changed
    STDMETHOD(Connect)(THIS_ /*[in]*/IDynamicPropertyNotify2* pSink) PURE;
    STDMETHOD(Disconnect)(THIS_ ) PURE;
};

typedef IDynamicProperty2 FAR* LPDYNAMICPROPERTY2;

如果我尝试按照 Visual Studio 中的建议“修复”错误,那么当我去构建时会发生这种情况

这是更改后的代码

// Property display nameD
void IDynamicProperty2.GetDisplayName(ref string szName)
{
    szName = "My integer property";
}
// Get the property description string
void IDynamicProperty2.GetDescription(ref string szName)
{
    szName = "This property is an integer";
}

// OPM will typically display these in an edit field
// optional: meta data representing property type name,
// ex. ACAD_ANGLE
void IDynamicProperty2.GetCurrentValueName(ref string szName)
{
    throw new System.NotImplementedException();
}

当我去构建时,我收到这些错误

Errors after trying to fix errors

c# c++ com autocad objectarx
1个回答
0
投票

我在c++项目的

IDynamicProperty2.h
文件中更改了这些声明

void GetDisplayName(
  [InteropServices::In,//added
   InteropServices::Out,
   InteropServices::MarshalAs(
    InteropServices::UnmanagedType::BStr
   )
  ] interior_ptr<System::String^> name);

void GetDescription(
  [InteropServices::In,//added
   InteropServices::Out,
   InteropServices::MarshalAs(
     InteropServices::UnmanagedType::BStr
   )
  ] interior_ptr<System::String^> description
);
void GetCurrentValueName(
  [InteropServices::In,//added
   InteropServices::Out,
   InteropServices::MarshalAs(
     InteropServices::UnmanagedType::BStr
   )
  ] interior_ptr<System::String^> name
);

然后更改了 C# 代码以使用

ref

void IDynamicProperty2.GetDisplayName(ref string szName)
{
    szName = "My integer property";
}

void IDynamicProperty2.GetDescription(ref string szName)
{
    szName = "This property is an integer";
}

void IDynamicProperty2.GetCurrentValueName(ref string szName)
{
    throw new System.NotImplementedException();
}

我在两个项目中都构建了这些更改,然后没有加载示例项目,效果很好!

© www.soinside.com 2019 - 2024. All rights reserved.