[返回博客](/cn/blog) # IFC SDK 和 SDAI：从集合中读取应用程序数据块

Egor Vorobyov 十二月 17, 2020 [\#ifc](/cn/blog/tag/ifc) [\#getting started](/cn/blog/tag/getting-started)

<a class="a2a_button_facebook"></a><a class="a2a_button_twitter"></a><a class="a2a_button_linkedin"></a>

IFC SDK 支持标准数据访问接口 (SDAI)，它提供了一个低级 API，用于操作使用 EXPRESS 模式定义的数据。本文介绍了如何从集合中读取应用程序数据块。

有关在 IFC SDK 中使用 SDAI 的详细信息，请参阅[本文](https://www.opendesign.com/blog/2020/october/working-standard-data-access-interface-oda-ifc-sdk)。

假设您的 IFC 模型包含以下实例：

```
#94 = IFCUNITASSIGNMENT ((#43,#45,#46,#50,#52,#55,#57,#58,#60,#64,#69,#71,#72, #73,#74,#75,#76,#77,#82,#86,#88,#92));
```

我们可以看到 IfcUnitAssignment 的一个实例。此实例有一个包含聚合的字段。此聚合由句柄 ID 填充。但是，如果我们查看表达式方案，我们会发现这是选择属性的聚合，而不是实例。因此，让我们读取它并提取选择数据。

首先，通过 ID 从模型中获取一个应用程序实例。使用 \_sdaiGetEntityById：

```
SdaiAppInstance applicationInstance = _sdaiGetEntityById(model, 94);
TEST_ASSERT(applicationInstance != NULL);
TEST_ASSERT(sdaiErrorQuery() == sdaiNO_ERR);
```

从应用程序实例中获取名为“units”的属性。检查聚合——它不应为空。为聚合实例调用函数 sdaiGetMemberCount。它应该返回一个大于零的值。

```
SdaiAggr  aggregate = NULL;
TEST_ASSERT(sdaiGetAttrBN(applicationInstance, "units", sdaiAGGR, &aggregate) != NULL);

TEST_ASSERT(sdaiGetMemberCount(aggregate) > 0);
```

使用迭代器功能访问聚合项：sdaiCreateIterator、sdaiBeginning 和 sdaiNext。

```
SdaiIterator aggregateIterator = sdaiCreateIterator(aggregate);
TEST_ASSERT(sdaiErrorQuery() == sdaiNO_ERR);

for (sdaiBeginning(aggregateIterator); sdaiNext(aggregateIterator);)
```

使用 sdaiCreateEmptyADB 创建一个空的 ADB 实例，并将指向此创建实例的指针传递给 sdaiGetAggrByIterator。sdaiGetAggrByIterator 应该从迭代器实例填充 ADB 数据：

```
SdaiADB adbToGet = sdaiCreateEmptyADB();

TEST_ASSERT(sdaiGetAggrByIterator(aggregateIterator, sdaiADB, &adbToGet) != NULL);
```

此时，我们应该使用 sdaiGetADBValue 从 ADB 中提取值。然后我们必须销毁 ADB 以避免内存泄漏：

```
SdaiInstance  instanceFromAdb = NULL;
TEST_ASSERT(sdaiGetADBValue(adbToGet, sdaiINSTANCE, &instanceFromAdb) != NULL);

sdaiDeleteADB(adbToGet);
```

有一种简单的方法可以从聚合中获取 ADB 值，而无需使用 ADB 值。我们可以使用 sdaiGetAggrByIterator 从聚合中请求一个类型化值，并且如果聚合中的 ADB 值类型可以转换为参数值类型，它会返回一个有效值：

```
SdaiInstance  instanceFromAdbSimpleGet = NULL;
TEST_ASSERT(sdaiGetAggrByIterator(aggregateIterator, 
 					    sdaiINSTANCE, 
&instanceFromAdbSimpleGet) != NULL);
```

要检查收到的值，请将其与使用 ADB 时收到的值进行比较：

```
TEST_ASSERT(instanceFromAdb == instanceFromAdbSimpleGet);
TEST_ASSERT(sdaiErrorQuery() == sdaiNO_ERR);
```

## 今天就开始行动

**免费试用 ODA 软件 60 天。  
无风险，无需信用卡。**

[免费试用](https://www.opendesign.com/cn/free-trial)
