Оболочка C # для acdbEntGet и acdbEntGetX

Мне нужна оболочка для 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-битных целых чисел (если я правильно помню)

0

Решение

За 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.

1

Другие решения

Поскольку мое редактирование ответа 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)

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector