问题遇到的现象和发生背景
问题相关代码,请勿粘贴截图
#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++的结构体
我想要达到的结果
希望能有一个好的解决方案,能让代码通过测试