You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在互联网数据传输中使用ASN.1?asn1c生成代码使用疑问

Understanding asn1c Output & Implementing Rectangle Serialization/Deserialization

Hey there! Let's tackle your questions one by one and walk you through a complete example to serialize and send your Rectangle data.

Why use INTEGER_t instead of int?

ASN.1's INTEGER type is designed to support arbitrary-precision integers (way larger than what a standard int or even long can hold). The INTEGER_t type generated by asn1c is a helper structure that wraps the raw integer data along with metadata needed for ASN.1 encoding/decoding:

  • It stores the integer as a byte buffer (to handle big numbers)
  • Tracks the length of that buffer
  • Includes internal context for encoding state

This aligns with ASN.1's flexibility, even if you're only using small integers right now—it's the compiler enforcing the standard.

What's with the _asn_ctx field in the struct?

That _asn_ctx isn't a nested struct you need to worry about—it's an internal context object used by asn1c's runtime to handle things like:

  • Parsing across buffer boundaries (useful for streaming data)
  • Tracking encoding/decoding state
  • Managing errors during the process

You don't need to modify or interact with _asn_ctx directly—it's handled automatically by the asn1c-provided functions. The Rectangle_t struct itself is straightforward: it just holds your two integer fields plus this internal bookkeeping data.

Step-by-Step: Serialize rect={10,20} and Send It

1. Compile the asn1c-generated files

First, compile all the generated .c files (including Rectangle.c, INTEGER.c, asn_SEQUENCE_OF.c, etc.—you'll see them in your directory) into object files:

gcc -c *.c

2. Example Code to Serialize, Send, and Deserialize

Here's a complete example that initializes your Rectangle, encodes it to BER format, simulates sending it, then decodes it back:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Rectangle.h"
#include "ber_encoder.h"
#include "ber_decoder.h"

int main() {
    // Step 1: Initialize the Rectangle struct
    Rectangle_t rect;
    memset(&rect, 0, sizeof(Rectangle_t)); // Zero-initialize all fields

    // Set height=10 and width=20 using asn1c helper functions
    if (asn_INTEGER_set(&rect.height, 10) != 0) {
        fprintf(stderr, "Failed to set height value\n");
        return 1;
    }
    if (asn_INTEGER_set(&rect.width, 20) != 0) {
        fprintf(stderr, "Failed to set width value\n");
        return 1;
    }

    // Step 2: Encode the Rectangle to BER format
    asn_enc_rval_t enc_result;
    uint8_t *ber_buffer = NULL;
    size_t ber_buffer_size = 0;

    // DER is a strict subset of BER, suitable for most use cases
    enc_result = der_encode_to_buffer(&asn_DEF_Rectangle, &rect, &ber_buffer, &ber_buffer_size);
    if (enc_result.encoded == -1) {
        fprintf(stderr, "Encoding failed: %s\n", enc_result.failed_type->name);
        return 1;
    }
    printf("Encoded BER buffer size: %zu bytes\n", ber_buffer_size);

    // Step 3: Simulate sending the buffer (in real code, use sockets/files)
    uint8_t *sent_buffer = malloc(ber_buffer_size);
    memcpy(sent_buffer, ber_buffer, ber_buffer_size);

    // Step 4: Decode the received buffer back to Rectangle_t
    Rectangle_t *decoded_rect = NULL;
    asn_dec_rval_t dec_result = ber_decode(NULL, &asn_DEF_Rectangle, (void **)&decoded_rect, sent_buffer, ber_buffer_size);

    if (dec_result.code != RC_OK) {
        fprintf(stderr, "Decoding failed at byte %zu\n", dec_result.consumed);
        return 1;
    }

    // Extract and print decoded values
    long height_val, width_val;
    asn_INTEGER_get(&decoded_rect->height, &height_val);
    asn_INTEGER_get(&decoded_rect->width, &width_val);
    printf("Decoded Rectangle: height=%ld, width=%ld\n", height_val, width_val);

    // Cleanup allocated memory properly
    ASN_STRUCT_FREE(asn_DEF_Rectangle, decoded_rect);
    free(ber_buffer);
    free(sent_buffer);

    return 0;
}

3. Compile and Run the Example

Link your example code with the compiled object files:

gcc -o rectangle_example rectangle_example.o *.o
./rectangle_example

Key Notes

  • Helper Functions: Always use asn_INTEGER_set() and asn_INTEGER_get() to convert between standard integers and INTEGER_t—never directly modify the internal fields of INTEGER_t.
  • Other Formats: For PER or XER encoding/decoding, replace the BER functions with per_encode_to_buffer()/per_decode() or xer_encode_to_buffer()/xer_decode() respectively.
  • Memory Safety: Use ASN_STRUCT_FREE() to clean up ASN.1 structures—it ensures all internal buffers are freed properly, avoiding memory leaks.

内容的提问来源于stack exchange,提问作者chenkh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:33:02