Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#用于acdbEntGet和acdbEntGetX的包装器_C#_C++_Pinvoke_Autocad_Objectarx - Fatal编程技术网

C#用于acdbEntGet和acdbEntGetX的包装器

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,

我需要一个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\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代码的人:请参阅上面的注释。