asn1c中ASN_SEQUENCE_ADD的使用方法
ASN_SEQUENCE_ADD是asn1c中自动生成的宏,用于将一个指定类型的结构体添加到一个SEQUENCE OF类型的结构体中。
其用法通常是这样的:
1、定义一个SEQUENCE OF类型的结构体对象,例如:
A_SEQUENCE_OF(MyStruct_t) mySeqOf;
这个结构体对象可以保存任意数量的MyStruct_t类型的结构体。
2、创建一个MyStruct_t类型的结构体对象
MyStruct_t *myStruct = (MyStruct_t *)malloc(sizeof(MyStruct_t));
3、设置myStruct的成员变量。
4、将myStruct添加到mySeqOf中
ASN_SEQUENCE_ADD(&mySeqOf, myStruct);
注意:添加的结构体必须已经分配了内存,并设置好了其成员变量的值。
5、示例
#include <stdio.h>
#include <stdlib.h>
#include <asn_application.h>
#include <MyModule.h>
int main() {
// 创建一个 MySequenceOf_t 类型的结构体对象
MySequenceOf_t mySeqOf;
memset(&mySeqOf, 0, sizeof(mySeqOf));
// 创建两个 MyStruct_t 类型的结构体对象,并设置成员变量
MyStruct_t *myStruct1 = (MyStruct_t *)malloc(sizeof(MyStruct_t));
MyStruct_t *myStruct2 = (MyStruct_t *)malloc(sizeof(MyStruct_t));
memset(myStruct1, 0, sizeof(MyStruct_t));
memset(myStruct2, 0, sizeof(MyStruct_t));
myStruct1->x = 1;
myStruct1->y = 2;
myStruct2->x = 3;
myStruct2->y = 4;
// 将 myStruct1 和 myStruct2 添加到 mySeqOf 中
ASN_SEQUENCE_ADD(&mySeqOf, myStruct1);
ASN_SEQUENCE_ADD(&mySeqOf, myStruct2);
// 输出 mySeqOf 中保存的结构体的值
for (int i = 0; i < mySeqOf.count; i++) {
printf("mySeqOf.array[%d]->x=%d, mySeqOf.array[%d]->y=%d\n",
i, mySeqOf.array[i]->x, i, mySeqOf.array[i]->y);
}
// 释放内存
ASN_STRUCT_FREE(asn_DEF_MyStruct, myStruct1);
ASN_STRUCT_FREE(asn_DEF_MyStruct, myStruct2);
ASN_STRUCT_FREE(asn_DEF_MySequenceOf, &mySeqOf);
return 0;
}
另一个示例
typedef struct student
{
char name[10];
int age;
}stu_t;
typedef struct test
{
A_SET_OF(stu_t) list;
}test_t;
//A_SET_OF(stu_t) list;
int main()
{
/* Write C code in this online editor and run it. */
test_t *a = (test_t*)malloc(sizeof(test_t));
a->list.count = 0;//注意此处初始化很重要,地址空间的值不一定为0
a->list.size = 0;
a->list.array = NULL;//此处赋为空,不然asn_set_add中的realloc会报错
printf("count %d\tsize %d\n",a->list.count,a->list.size);
stu_t *stu1 = (stu_t*)malloc(sizeof(stu_t));
stu_t *stu2 = (stu_t*)malloc(sizeof(stu_t));
memcpy(stu1->name, "xiaoming", sizeof("xiaoming"));
stu1->age = 10;
memcpy(stu2->name, "xiaohong", sizeof("xiaohong"));
stu2->age = 11;
printf("count %d\tsize %d\n",a->list.count,a->list.size);
asn_set_add(&a->list, stu1);
asn_set_add(&a->list, stu2);
printf("stu1.name: %s, stu1.age: %d,stu2.name: %s, stu2.age: %d\n",a->list.array[0]->name, a->list.array[0]->age, a->list.array[1]->name, a->list.array[1]->age);
printf("count %d\tsize %d\n",a->list.count,a->list.size);
return 0;
}
6、sequence的释放方法
/*
* Could not use set_of_empty() because of (*free)
* incompatibility.
*/
for(i = 0; i < list->count; i++) {
void *memb_ptr = list->array[i];
if(memb_ptr)
ASN_STRUCT_FREE(*elm->type, memb_ptr);
}
list->count = 0; /* No meaningful elements left */
asn_set_empty(list); /* Remove (list->array) */
7、sequence 方法源码
/*-
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
#include <asn_SET_OF.h>
#include <errno.h>
/*
* Add another element into the set.
*/
int
asn_set_add(void *asn_set_of_x, void *ptr) {
asn_anonymous_set_ *as = _A_SET_FROM_VOID(asn_set_of_x);
if(as == 0 || ptr == 0) {
errno = EINVAL; /* Invalid arguments */
return -1;
}
/*
* Make sure there's enough space to insert an element.
*/
if(as->count == as->size) {
int _newsize = as->size ? (as->size << 1) : 4;
void *_new_arr;
_new_arr = REALLOC(as->array, _newsize * sizeof(as->array[0]));
if(_new_arr) {
as->array = (void **)_new_arr;
as->size = _newsize;
} else {
/* ENOMEM */
return -1;
}
}
as->array[as->count++] = ptr;
return 0;
}
void
asn_set_del(void *asn_set_of_x, int number, int _do_free) {
asn_anonymous_set_ *as = _A_SET_FROM_VOID(asn_set_of_x);
if(as) {
void *ptr;
if(number < 0 || number >= as->count)
return;
if(_do_free && as->free) {
ptr = as->array[number];
} else {
ptr = 0;
}
as->array[number] = as->array[--as->count];
/*
* Invoke the third-party function only when the state
* of the parent structure is consistent.
*/
if(ptr) as->free(ptr);
}
}
/*
* Free the contents of the set, do not free the set itself.
*/
void
asn_set_empty(void *asn_set_of_x) {
asn_anonymous_set_ *as = _A_SET_FROM_VOID(asn_set_of_x);
if(as) {
if(as->array) {
if(as->free) {
while(as->count--)
as->free(as->array[as->count]);
}
FREEMEM(as->array);
as->array = 0;
}
as->count = 0;
as->size = 0;
}
}