Мне нужна оболочка для acdbEntGet и acdbEntGetX в C #. Эти функции расположены в 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 #, но эти две функции — нет. Интересно, почему.
Да, и кто-то может спросить, зачем мне эти функции … Ответ в том, что я хотел бы вернуть список на Лисп, который можно передать непосредственно (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-битных целых чисел (если я правильно помню)
За 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.
Поскольку мое редактирование ответа 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)