acdbEntGet 和 acdbEntGetX 的 C# 包装器

Posted

技术标签:

【中文标题】acdbEntGet 和 acdbEntGetX 的 C# 包装器【英文标题】:C# wrapper for acdbEntGet and acdbEntGetX 【发布时间】:2015-05-11 08:54:54 【问题描述】:

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

两个函数的返回值(一个 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 位整数组成的数组(如果我没记错的话)

【问题讨论】:

你能发布C头定义吗? 好的,问题已编辑。 不能说因为我没有AutoCAD,但是如果函数返回一个结构,你需要按照这里的步骤操作:***.com/questions/779444/… 【参考方案1】:

对于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代码。

【讨论】:

谢谢,麦克森斯。更正您的代码(并编辑您的答案)后,它起作用了。 acdbGetAdsName64 的第一个参数必须是外部引用。 ResultBuffer 的声明不能在 then 语句中进行。 嗯...好像我的编辑被拒绝了(?!)。不管怎样,谢谢。对于那些无法编译 Maxences 代码的人:请参阅上面的评论。【参考方案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) 中

【讨论】:

以上是关于acdbEntGet 和 acdbEntGetX 的 C# 包装器的主要内容,如果未能解决你的问题,请参考以下文章

第三十一节:扫盲并发和并行同步和异步进程和线程阻塞和非阻塞响应和吞吐等

shell中$()和 ` `${}${!}${#}$[] 和$(()),[ ] 和(( ))和 [[ ]]

Java基础8---面向对象代码块和继承和this和super和重写和重载和final

Java基础8---面向对象代码块和继承和this和super和重写和重载和final

JS中some()和every()和join()和concat()和pop(),push(),shift(),unshfit()和map()和filter()

malloc和free,brk和sbrk和mmap和munmap的使用和关系以及内存分配的原理