acdbEntGet 和 acdbEntGetX 的 C# 包装器

C# wrapper for acdbEntGet and acdbEntGetX

我需要在 C# 中对 acdbEntGet 和 acdbEntGetX 进行包装。这些函数位于 accore.dll (AutoCAD 2014) 中,我试过这个:

[DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto, EntryPoint = "acdbEntGetX")]
public static extern IntPtr acdbEntGetX(Int64 e, IntPtr app);

[DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto, EntryPoint = "acdbEntGet")]
public static extern IntPtr acdbEntGet(Int64 e);

两个函数的 return 值(一个 IntPtr)始终为 0。没有错误或异常。

几乎每个 ObjectARX C++ 函数都包含在 C# 托管库中,但这两个函数不是。我想知道为什么。

哦,有人可能会问我为什么需要这些函数...答案是我想 return 一个 Lisp 列表,它可以直接给 (entmake) 而不需要修改。这是用 acdbEntGet 和 acdbEntGetX 完成的。创建列表 "by hand" 是一个选项,但这不是我想要的(是的,我知道如何在 C# ObjectARX 中创建列表):)

编辑:以下是这些函数在 C++ 中的定义方式

struct resbuf *acdbEntGetX (const ads_name ent, const struct resbuf *args);
struct resbuf *acdbEntGet (const ads_name ent);

struct resbuf是adsdef.h

中定义的链表
struct resbuf {                                                  
        struct resbuf *rbnext; 
        short restype;
        union ads_u_val resval;
};

ads_name 是两个 64 位整数的数组(如果我没记错的话)

对于entget,应该是这样的:

public struct ads_name
{
    public IntPtr a;
    public IntPtr b;
};

[DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl]
static extern IntPtr acdbEntGet(ads_name objName);

这样使用:

IntPtr res = acdbEntGet(name);
if (res != IntPtr.Zero)
  ResultBuffer rb = ResultBuffer.Create(res, true);

要将 ObjectId 转换为 ads_name,您必须使用 acdbGetAdsName:

[DllImport("acdb19.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint="?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z"]
static extern ErrorStatus acdbGetAdsName64(ads_name objName, ObjectId id);

this post中,您可以在VB.NET中找到完整代码。

由于我对 Maxences 答案的编辑被拒绝,我将在此处重写正确的解决方案。我还包含了 acdbEntGetX

的代码
[DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr acdbEntGet(AdsName objName);

[DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr acdbEntGetX(AdsName objName, IntPtr app);

[DllImport("acdb19.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z")]
static extern ErrorStatus acdbGetAdsName64(out AdsName objName, ObjectId id);

示例:

ResultBuffer app = new ResultBuffer();
app.Add(new TypedValue((int)LispDataType.Text, "*"));

AdsName name = new AdsName();
acdbGetAdsName64(out name, o);

IntPtr res = acdbEntGetX(name, app.UnmanagedObject);
ResultBuffer rb;
if (res != IntPtr.Zero) rb = ResultBuffer.Create(res, true);

不需要结构 ads_name,因为它在程序集 acdbmgd.dll (AdsName)