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()