qq_27068451
2022-08-19 10:39
采纳率: 50%
浏览 180

C#调用C++结构体,以接口的形式

问题遇到的现象和发生背景

img

img

img

问题相关代码,请勿粘贴截图
#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("d0f45feb-71d5-44ea-B1A0-6E2F27B2085D")]
                [InteropServices::InterfaceTypeAttribute(InteropServices::ComInterfaceType::InterfaceIsIUnknown)]
                [InteropServices::ComVisible(true)]
                public interface class IOPMPropertyExpander2
                {
                    // 获得元素值
                    // DISPID dispID
                    // IUnknown * pUnk
                    // DWORD dwCookie
                    // VARIANT * pVarOut
                    void GetElementValue(
                        [InteropServices::In] System::Int32 dispID,
                        [InteropServices::In, InteropServices::MarshalAs(InteropServices::UnmanagedType::IUnknown)] Object^ pUnk,
                        [InteropServices::In] System::UInt32 dwCookie,
                        [InteropServices::In, InteropServices::Out, InteropServices::MarshalAs(InteropServices::UnmanagedType::Struct)] interior_ptr< Object^> pVarOut
                    );

                    // 设置元素值
                    // DISPID dispID
                    // IUnknown * pUnk
                    // DWORD dwCookie
                    // VARIANT VarIn
                    void SetElementValue(
                        [InteropServices::In] System::Int32 dispID,
                        [InteropServices::In, InteropServices::MarshalAs(InteropServices::UnmanagedType::IUnknown)] Object^ pUnk,
                        [InteropServices::In] System::UInt32 dwCookie,
                        [InteropServices::In, InteropServices::Out, InteropServices::MarshalAs(InteropServices::UnmanagedType::Struct)] interior_ptr< Object^> VarIn
                    );

                    // 获取元素分组
                    // DISPID dispID
                    // IUnknown * pUnk
                    // short * groupingNumber
                    void GetElementGrouping(
                        [InteropServices::In] System::Int32 dispID,
                        [InteropServices::In, InteropServices::MarshalAs(InteropServices::UnmanagedType::IUnknown)] Object^ pUnk,
                        [InteropServices::In, InteropServices::Out, InteropServices::MarshalAs(InteropServices::UnmanagedType::I2)] interior_ptr<short> groupingNumber
                    );

                    // 获取组个数
                    // DISPID dispID
                    // IUnknown * pUnk
                    // long * nGroupCnt
                    void GetGroupCount(
                        [InteropServices::In] System::Int32 dispID,
                        [InteropServices::In, InteropServices::MarshalAs(InteropServices::UnmanagedType::IUnknown)] Object^ pUnk,
                        [InteropServices::In, InteropServices::Out, InteropServices::MarshalAs(InteropServices::UnmanagedType::I8)] interior_ptr<long> nGroupCnt
                    );

                    // 获取元素字符串
                    // DISPID dispID
                    // IUnknown * pUnk
                    // OPMLPOLESTR __RPC_FAR * pCaStringsOut
                    // OPMDWORD __RPC_FAR * pCaCookiesOut
                    void GetElementStrings(
                        [InteropServices::In] System::Int32 dispID,
                        [InteropServices::In, InteropServices::MarshalAs(InteropServices::UnmanagedType::IUnknown)] Object pUnk,
                        [InteropServices::In, InteropServices::Out, InteropServices::MarshalAs(InteropServices::UnmanagedType::Struct)] interior_ptr<OPMLPOLESTR> pCaStringsOut,
                        [InteropServices::In, InteropServices::Out, InteropServices::MarshalAs(InteropServices::UnmanagedType::Struct)] interior_ptr<OPMDWORD> pCaCookiesOut
                    );

                };
                //typedef public struct  tagOPMLPOLESTR
                //{
                //    ULONG cElems;
                //    /* [size_is] */ LPOLESTR __RPC_FAR* pElems;
                //} OPMLPOLESTR;

                //typedef struct tagOPMLPOLESTR __RPC_FAR* LPOPMLPOLESTR;

                //typedef public struct  tagOPMDWORD
                //{
                //    ULONG cElems;
                //    /* [size_is] */ DWORD __RPC_FAR* pElems;
                //} OPMDWORD;

                //typedef struct tagOPMDWORD __RPC_FAR* LPOPMDWORD;
            }
        }
    }
}


    #region 自定义属性
    [
    Guid("EC0AB7F1-5D92-4FF1-96AE-7AC537C1347E"),
    ProgId("OPMNETSample.ExpanderProperty.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 ExpanderPropertyDemo : IDynamicProperty2, ICategorizeProperties, IOPMPropertyExpander2
    {
        private IDynamicPropertyNotify2 property_notify_ = null;
        private int m_numberOfVertices;
        private Point3d[] vertices;
        private int currrntIndex = 0; // Save the current vertex's index

        // 默认构造函数
        public ExpanderPropertyDemo()
        {
            m_numberOfVertices = 5;
            vertices = new Point3d[m_numberOfVertices];
            vertices[0] = new Point3d(1000, 1000, 0);
            vertices[1] = new Point3d(2000, 2000, 0);
            vertices[2] = new Point3d(3000, 3000, 0);
            vertices[3] = new Point3d(4000, 4000, 0);
            vertices[4] = new Point3d(5000, 5000, 0);

        }

        void IDynamicProperty2.Connect(object pSink)
        {
            property_notify_ = (IDynamicPropertyNotify2)pSink;
        }

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

        void ICategorizeProperties.GetCategoryName(int propcat, uint lcid, out string pbstrName)
        {
            pbstrName = "扩展属性";
        }

        void IDynamicProperty2.GetCurrentValueData(object pUnk, ref object varData)
        {
            varData = null;
        }

        void IDynamicProperty2.GetCurrentValueName(out string name)
        {
            name = null;
        }

        void IDynamicProperty2.GetCurrentValueType(out ushort pVarType)
        {
            pVarType = 12; // VT_VARIANT = 12
        }

        void IDynamicProperty2.GetDescription(out string description)
        {
            description = "扩展动态属性演示";
        }

        void IDynamicProperty2.GetDisplayName(out string name)
        {
            name = "当前顶点";
        }

        void IOPMPropertyExpander2.GetElementGrouping(int dispID, object pUnk, ref short groupingNumber)
        {
            groupingNumber = 3;
        }

        void IOPMPropertyExpander2.GetElementValue(int dispID, object pUnk, uint dwCookie, ref object pVarOut)
        {
            int index = (int)dwCookie / 3;
            int subIndex = ((int)dwCookie - index * 3) % 3;
            pVarOut = vertices[index][subIndex];
            currrntIndex = index;
        }

        void IOPMPropertyExpander2.GetGroupCount(int dispID, object pUnk, ref int nGroupCnt)
        {
            nGroupCnt = m_numberOfVertices;
        }

        void IDynamicProperty2.GetGUID(out Guid propGUID)
        {
            propGUID = new Guid("9CAF41C2-CA86-4ffb-B05A-AC43C424D076");
        }

        void IDynamicProperty2.IsPropertyEnabled(object pUnk, out int bEnabled)
        {
            bEnabled = 1;
        }

        void IDynamicProperty2.IsPropertyReadOnly(out int bReadonly)
        {
            bReadonly = 0;
        }

        void ICategorizeProperties.MapPropertyToCategory(int dispid, out int ppropcat)
        {
            ppropcat = 4;
        }

        void IDynamicProperty2.SetCurrentValueData(object pUnk, object varData)
        {
            /*
                         * when pick a point, this method is called.
                         */
            double[] xyz = (double[])varData;
            vertices[currrntIndex] = new Point3d(xyz[0], xyz[1], xyz[2]);
        }

        void IOPMPropertyExpander2.SetElementValue(int dispID, object pUnk, uint dwCookie, ref object VarIn)
        {
            int index = (int)dwCookie / 3;
            int subIndex = ((int)dwCookie - index * 3) % 3;
            Point3d point = vertices[index];
            if (subIndex == 0)
            {
                vertices[index] = new Point3d((double)VarIn, point.Y, point.Z);
            }
            else if (subIndex == 1)
            {
                vertices[index] = new Point3d(point.X, (double)VarIn, point.Z);
            }
            else if (subIndex == 2)
            {
                vertices[index] = new Point3d(point.X, point.Y, (double)VarIn);
            }
        }

/*        public unsafe void GetElementStrings(
            [In] int dispID,
            [In, MarshalAs(UnmanagedType.IUnknown)] object pUnk,
            [In, Out, MarshalAs(UnmanagedType.Struct)] ref OPMLPOLESTR pCaStringsOut,
            [In, Out, MarshalAs(UnmanagedType.Struct)] ref OPMDWORD pCaCookiesOut)
        {
            List<string> strings = new List<string> { "顶点 X 坐标", "顶点 Y 坐标", "顶点 Z 坐标" };
            List<uint> values = new List<uint> { 0, 1, 2 };
            pCaStringsOut = OPMUtils.CreateOPMLPOLESTR(strings);
            pCaCookiesOut = OPMUtils.CreateOPMDWORD(values);
        }*/

        public void Initialize()
        {
            ExpanderPropertyDemo epd = new ExpanderPropertyDemo();
        }

        public void Terminate()
        {
            throw new NotImplementedException();
        }
    }
    #endregion
运行结果及报错内容

一种结果是显示不支持语法,
另一种结果是实现接口后,还是出现错误

我的解答思路和尝试过的方法

C#调用C++的结构体,以接口类的形式调用
尝试过网络一些C#调用C++的结构体方式,显示还是报错,导入C++结构体,是后面再指向C++的结构体,而接口实现,则是开始就指向C++的结构体

我想要达到的结果

希望能有一个好的解决方案,能让代码通过测试

2条回答 默认 最新

相关推荐 更多相似问题