C#用于acdbEntGet和acdbEntGetX的包装器
我需要一个C#中的acdbEntGet和acdbEntGetX的包装器。这些函数位于accore.dll(AutoCAD 2014)中,我尝试了以下方法:C#用于acdbEntGet和acdbEntGetX的包装器,c#,c++,pinvoke,autocad,objectarx,C#,C++,Pinvoke,Autocad,Objectarx,我需要一个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,
[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\u 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);
像这样使用它:
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_名称,必须使用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中找到完整的代码。对于
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);
像这样使用它:
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_名称,必须使用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中找到完整的代码。由于我对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_名称,因为它位于程序集acdbmgd.dll(AdsName)中,因为我对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_名称,因为它在程序集acdbmgd.dll(AdsName)中。你能发布C头定义吗?好的,问题已编辑。我不能说,因为我没有AutoCAD,但是如果函数返回结构,你需要按照这里的步骤:你能发布C头定义吗?好的,问题已编辑。不能说我没有AutoCAD,但如果函数返回结构,是否需要按照此处的步骤操作:谢谢,Maxence。在更正了代码(并编辑了答案)后,它成功了。acdbGetAdsName64的第一个参数需要是out引用。ResultBuffer的声明不能在“then”语句中完成。嗯。。。似乎我的编辑被拒绝了(?)。无论如何谢谢对于那个些不能编译Maxence代码的人:请看上面的评论。谢谢,Maxence。在更正了代码(并编辑了答案)后,它成功了。acdbGetAdsName64的第一个参数需要是out引用。ResultBuffer的声明不能在“then”语句中完成。嗯。。。似乎我的编辑被拒绝了(?)。无论如何谢谢对于那个些不能编译Maxences代码的人:请参阅上面的注释。