0

我需要 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);

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

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

哦,有人可能会问我为什么需要这些函数……答案是我想将一个列表返回给 Lisp,它可以直接提供(entmake)而无需修改。这是通过 acdbEntGet 和 acdbEntGetX 完成的。“手动”创建列表是一个选项,但这不是我想要的(是的,我知道如何在 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 位整数的数组(如果我没记错的话)

4

2 回答 2

2

对于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);

这篇文章中,您可以找到 VB.NET 中的完整代码。

于 2015-05-11T13:20:00.510 回答
2

由于我对 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) 中

于 2015-05-13T04:24:46.390 回答