在 Autocad .Net WCF 插件中保留 ObjectId 引用

Keeping ObjectId reference in an Autocad .Net WCF plugin

有一个 .Net Autocad 插件,其中使用 WCF 服务调用方法 在 Autocad 外部的另一个进程上。 Autocad 实体包装在自定义 类 中并通过 WCF 传递。一旦调用 returns 插件需要将结果写回 Autocad 数据库。

问题来了:需要ObjectId来获取对象并写回结果; WCF 序列化数据而 ObjectId 不可序列化。所以我无权访问该对象。

这个有workaround/solution吗?

您必须序列化 ObjectId 的值句柄,因为它不可序列化:

[Serializable]
public class TobeSerialized
{
    private long idHandleValue;
    [NonSerialized]
    private ObjectId id;

    public TobeSerialized()
    {
        this.idHandleValue = id.Handle.Value;
    }
public ObjectId GetObjectId(Database database, long handleValue)
    {
        Handle handle = new Handle(handleValue);
        ObjectId id = database.GetObjectId(false, handle, 0);
        return id;
    }
}

然后,当你反序列化你的 Class object 时,你将能够通过调用方法 GetObjectId(Database database, long handleValue)

来获得 objectId

您可以使用 属性 ObjectId.OldIdPtr,这是一个 IntPtr(可序列化)。要取回您的 ObjectId,只需执行以下操作:

var id = new ObjectId(oldIdPtr);

这是比使用句柄(需要查找)更直接的方法

对于您的每个实体,您都可以在没有中介 (objectId) 的情况下直接获得句柄。 使用 Entity.Handle 属性。 来自 autocad 指南

数据库对象中包含的每个对象都分配了几个唯一的 ID。您可以访问对象的独特方式是: 实体句柄 对象ID 实例指针 最常见的方法是通过对象 ID 访问对象。如果您的项目同时使用 COM 互操作和托管 .NET API,则对象 ID 可以很好地工作。如果您创建自定义 AutoLISP 函数,您可能需要使用实体句柄。 句柄在 AutoCAD 会话之间是持久的,因此如果您需要将图形信息导出到外部文件(稍后可能需要用于更新图形),它们是访问对象的最佳方式。数据库中对象的 ObjectId 仅在数据库加载到内存时存在。数据库关闭后,分配给对象的对象 ID 将不复存在,下次打开数据库时可能会有所不同。