## Overview Step-by-step tutorial for creating your first DAP SDK application. This guide walks through building a complete application that demonstrates core DAP SDK functionality including initialization, configuration, logging, basic cryptography, and proper cleanup. **What you'll learn:** - DAP SDK initialization and configuration - Basic logging and error handling - Memory management best practices - Cryptographic operations - Application lifecycle management - Module integration patterns **Prerequisites:** - DAP SDK installed ([[Installation Guide|Installation Guide]]) - Basic C programming knowledge - Development environment configured ## Project Setup ### Create Project Directory ```bash # Create project directory mkdir my-first-dap-app cd my-first-dap-app # Create source directory mkdir src mkdir include mkdir build ``` ### Project Structure ``` my-first-dap-app/ ├── src/ │ ├── main.c │ ├── app_config.c │ └── crypto_demo.c ├── include/ │ ├── app_config.h │ └── crypto_demo.h ├── CMakeLists.txt ├── README.md └── build/ ``` ## Basic Application ### Simple Hello World Create `src/main.c`: ```c #include <stdio.h> #include <stdlib.h> #include <dap/dap_common.h> int main(int argc, char *argv[]) { printf("Starting my first DAP SDK application...\n"); // Initialize DAP SDK if (dap_common_init("MyFirstDAPApp", NULL) != 0) { fprintf(stderr, "Failed to initialize DAP SDK\n"); return EXIT_FAILURE; } printf("DAP SDK initialized successfully!\n"); printf("Application: %s\n", "MyFirstDAPApp"); printf("SDK Version: %s\n", dap_get_version()); // Cleanup dap_common_deinit(); printf("Application terminated successfully.\n"); return EXIT_SUCCESS; } ``` ### Build Configuration Create `CMakeLists.txt`: ```cmake cmake_minimum_required(VERSION 3.16) project(MyFirstDAPApp VERSION 1.0.0 LANGUAGES C) # Set C standard set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) # Find DAP SDK find_package(PkgConfig REQUIRED) pkg_check_modules(DAP_SDK REQUIRED dap-sdk) # Include directories include_directories(include) include_directories(${DAP_SDK_INCLUDE_DIRS}) # Compile flags add_compile_options(${DAP_SDK_CFLAGS_OTHER}) # Source files set(SOURCES src/main.c ) # Create executable add_executable(${PROJECT_NAME} ${SOURCES}) # Link libraries target_link_libraries(${PROJECT_NAME} ${DAP_SDK_LIBRARIES}) target_link_directories(${PROJECT_NAME} PRIVATE ${DAP_SDK_LIBRARY_DIRS}) # Installation install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) ``` ### Build and Run ```bash # Navigate to build directory cd build # Configure build cmake .. # Build the application make # Run the application ./MyFirstDAPApp ``` Expected output: ``` Starting my first DAP SDK application... DAP SDK initialized successfully! Application: MyFirstDAPApp SDK Version: 1.0.0 Application terminated successfully. ``` ## Enhanced Application with Configuration ### Configuration Management Create `include/app_config.h`: ```c #ifndef APP_CONFIG_H #define APP_CONFIG_H #include <stdbool.h> typedef struct app_config { char *app_name; char *log_file; char *log_level; bool debug_mode; int worker_threads; size_t memory_pool_size; } app_config_t; // Configuration functions app_config_t* app_config_create(void); void app_config_destroy(app_config_t *config); int app_config_load_from_file(app_config_t *config, const char *config_file); int app_config_apply(const app_config_t *config); void app_config_print(const app_config_t *config); #endif // APP_CONFIG_H ``` Create `src/app_config.c`: ```c #include "app_config.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dap/dap_common.h> #include <dap/dap_config.h> app_config_t* app_config_create(void) { app_config_t *config = DAP_NEW_Z(app_config_t); if (!config) { return NULL; } // Set default values config->app_name = dap_strdup("MyFirstDAPApp"); config->log_file = dap_strdup("app.log"); config->log_level = dap_strdup("info"); config->debug_mode = false; config->worker_threads = 4; config->memory_pool_size = 64 * 1024 * 1024; // 64MB return config; } void app_config_destroy(app_config_t *config) { if (config) { DAP_DELETE(config->app_name); DAP_DELETE(config->log_file); DAP_DELETE(config->log_level); DAP_DELETE(config); } } int app_config_load_from_file(app_config_t *config, const char *config_file) { if (!config || !config_file) { return -1; } // Load configuration file if (dap_config_load(config_file) != 0) { log_it_warning("Could not load config file %s, using defaults", config_file); return 0; // Not fatal, continue with defaults } // Read configuration values const char *app_name = dap_config_get_string("app", "name", config->app_name); if (app_name && strcmp(app_name, config->app_name) != 0) { DAP_DELETE(config->app_name); config->app_name = dap_strdup(app_name); } const char *log_file = dap_config_get_string("logging", "file", config->log_file); if (log_file && strcmp(log_file, config->log_file) != 0) { DAP_DELETE(config->log_file); config->log_file = dap_strdup(log_file); } const char *log_level = dap_config_get_string("logging", "level", config->log_level); if (log_level && strcmp(log_level, config->log_level) != 0) { DAP_DELETE(config->log_level); config->log_level = dap_strdup(log_level); } config->debug_mode = dap_config_get_bool("app", "debug", config->debug_mode); config->worker_threads = dap_config_get_int("threads", "workers", config->worker_threads); config->memory_pool_size = dap_config_get_size("memory", "pool_size", config->memory_pool_size); return 0; } int app_config_apply(const app_config_t *config) { if (!config) { return -1; } // Apply DAP SDK configuration dap_config_set_string("core", "log_level", config->log_level); dap_config_set_string("core", "log_file", config->log_file); dap_config_set_bool("core", "debug_mode", config->debug_mode); dap_config_set_int("io", "worker_threads", config->worker_threads); dap_config_set_size("memory", "pool_size", config->memory_pool_size); return 0; } void app_config_print(const app_config_t *config) { if (!config) { return; } log_it_info("Application Configuration:"); log_it_info(" App Name: %s", config->app_name); log_it_info(" Log File: %s", config->log_file); log_it_info(" Log Level: %s", config->log_level); log_it_info(" Debug Mode: %s", config->debug_mode ? "enabled" : "disabled"); log_it_info(" Worker Threads: %d", config->worker_threads); log_it_info(" Memory Pool: %zu bytes", config->memory_pool_size); } ``` ### Cryptography Demo Create `include/crypto_demo.h`: ```c #ifndef CRYPTO_DEMO_H #define CRYPTO_DEMO_H #include <stddef.h> // Crypto demo functions int crypto_demo_hash_example(void); int crypto_demo_sign_example(void); int crypto_demo_encrypt_example(void); void crypto_demo_run_all(void); #endif // CRYPTO_DEMO_H ``` Create `src/crypto_demo.c`: ```c #include "crypto_demo.h" #include <stdio.h> #include <string.h> #include <dap/dap_common.h> #include <dap/dap_crypto.h> int crypto_demo_hash_example(void) { log_it_info("=== Hash Example ==="); const char *message = "Hello, DAP SDK World!"; dap_hash_fast_t hash; // Compute hash if (dap_hash_fast(message, strlen(message), &hash) != 0) { log_it_error("Failed to compute hash"); return -1; } // Convert hash to hex string char hex_hash[DAP_HASH_FAST_SIZE * 2 + 1]; dap_bin2hex(hex_hash, hash.raw, DAP_HASH_FAST_SIZE); log_it_info("Message: %s", message); log_it_info("Hash (hex): %s", hex_hash); // Verify hash consistency dap_hash_fast_t hash2; dap_hash_fast(message, strlen(message), &hash2); if (memcmp(&hash, &hash2, sizeof(hash)) == 0) { log_it_info("Hash verification: SUCCESS (hashes match)"); } else { log_it_error("Hash verification: FAILED (hashes don't match)"); return -1; } return 0; } int crypto_demo_sign_example(void) { log_it_info("=== Digital Signature Example ==="); const char *message = "This message is digitally signed"; // Generate key pair dap_enc_key_t *key = dap_enc_key_new_generate(DAP_ENC_KEY_TYPE_SIG_DILITHIUM, NULL, 0, NULL, 0, 0); if (!key) { log_it_error("Failed to generate key pair"); return -1; } log_it_info("Generated key pair for signing"); // Sign the message dap_sign_t *signature = dap_sign_create(key, message, strlen(message), 0); if (!signature) { log_it_error("Failed to create signature"); dap_enc_key_delete(key); return -1; } log_it_info("Message signed successfully"); log_it_info("Signature size: %zu bytes", signature->header.sign_size); // Verify the signature if (dap_sign_verify(signature, key) == 1) { log_it_info("Signature verification: SUCCESS"); } else { log_it_error("Signature verification: FAILED"); DAP_DELETE(signature); dap_enc_key_delete(key); return -1; } // Cleanup DAP_DELETE(signature); dap_enc_key_delete(key); return 0; } int crypto_demo_encrypt_example(void) { log_it_info("=== Encryption Example ==="); const char *plaintext = "This is secret data that will be encrypted"; size_t plaintext_size = strlen(plaintext); // Generate encryption key dap_enc_key_t *key = dap_enc_key_new_generate(DAP_ENC_KEY_TYPE_RLWE_NEWHOPE, NULL, 0, NULL, 0, 0); if (!key) { log_it_error("Failed to generate encryption key"); return -1; } log_it_info("Generated encryption key"); log_it_info("Plaintext: %s", plaintext); log_it_info("Plaintext size: %zu bytes", plaintext_size); // Encrypt the data uint8_t *encrypted_data = NULL; size_t encrypted_size = 0; encrypted_data = dap_enc_key_encrypt(key, plaintext, plaintext_size, &encrypted_size); if (!encrypted_data) { log_it_error("Failed to encrypt data"); dap_enc_key_delete(key); return -1; } log_it_info("Data encrypted successfully"); log_it_info("Encrypted size: %zu bytes", encrypted_size); // Decrypt the data uint8_t *decrypted_data = NULL; size_t decrypted_size = 0; decrypted_data = dap_enc_key_decrypt(key, encrypted_data, encrypted_size, &decrypted_size); if (!decrypted_data) { log_it_error("Failed to decrypt data"); DAP_DELETE(encrypted_data); dap_enc_key_delete(key); return -1; } log_it_info("Data decrypted successfully"); log_it_info("Decrypted size: %zu bytes", decrypted_size); // Verify decryption if (decrypted_size == plaintext_size && memcmp(plaintext, decrypted_data, plaintext_size) == 0) { log_it_info("Decryption verification: SUCCESS"); log_it_info("Decrypted text: %.*s", (int)decrypted_size, decrypted_data); } else { log_it_error("Decryption verification: FAILED"); DAP_DELETE(encrypted_data); DAP_DELETE(decrypted_data); dap_enc_key_delete(key); return -1; } // Cleanup DAP_DELETE(encrypted_data); DAP_DELETE(decrypted_data); dap_enc_key_delete(key); return 0; } void crypto_demo_run_all(void) { log_it_info("Starting cryptography demonstrations..."); if (crypto_demo_hash_example() == 0) { log_it_info("Hash example completed successfully\n"); } else { log_it_error("Hash example failed\n"); } if (crypto_demo_sign_example() == 0) { log_it_info("Digital signature example completed successfully\n"); } else { log_it_error("Digital signature example failed\n"); } if (crypto_demo_encrypt_example() == 0) { log_it_info("Encryption example completed successfully\n"); } else { log_it_error("Encryption example failed\n"); } log_it_info("All cryptography demonstrations completed."); } ``` ### Enhanced Main Application Update `src/main.c`: ```c #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <dap/dap_common.h> #include "app_config.h" #include "crypto_demo.h" // Global variables static app_config_t *g_app_config = NULL; static volatile bool g_running = true; // Signal handler for graceful shutdown void signal_handler(int signal) { switch (signal) { case SIGINT: case SIGTERM: log_it_info("Received shutdown signal (%d), initiating graceful shutdown...", signal); g_running = false; break; default: log_it_warning("Received unexpected signal: %d", signal); break; } } // Application initialization int app_init(int argc, char *argv[]) { printf("Initializing DAP SDK application...\n"); // Create configuration g_app_config = app_config_create(); if (!g_app_config) { fprintf(stderr, "Failed to create application configuration\n"); return -1; } // Load configuration from file if provided const char *config_file = (argc > 1) ? argv[1] : "app.conf"; app_config_load_from_file(g_app_config, config_file); // Apply configuration to DAP SDK if (app_config_apply(g_app_config) != 0) { fprintf(stderr, "Failed to apply configuration\n"); return -1; } // Initialize DAP SDK if (dap_common_init(g_app_config->app_name, NULL) != 0) { fprintf(stderr, "Failed to initialize DAP SDK\n"); return -1; } // Print configuration app_config_print(g_app_config); log_it_info("Application initialized successfully"); log_it_info("SDK Version: %s", dap_get_version()); return 0; } // Application cleanup void app_cleanup(void) { log_it_info("Cleaning up application..."); // Cleanup DAP SDK dap_common_deinit(); // Cleanup configuration app_config_destroy(g_app_config); g_app_config = NULL; printf("Application cleanup completed.\n"); } // Main application loop int app_run(void) { log_it_info("Starting application main loop..."); // Run cryptography demonstrations crypto_demo_run_all(); // Simulate some work log_it_info("Application is running... (Press Ctrl+C to stop)"); int iteration = 0; while (g_running) { iteration++; if (iteration % 10 == 0) { log_it_info("Application heartbeat - iteration %d", iteration); // Show memory statistics dap_memory_stats_t stats; if (dap_memory_get_stats(&stats) == 0) { log_it_debug("Memory stats - allocated: %zu bytes, peak: %zu bytes", stats.bytes_allocated, stats.peak_allocated); } } // Sleep for 1 second sleep(1); // Break after 30 iterations if no signal received if (iteration >= 30) { log_it_info("Completed 30 iterations, shutting down..."); break; } } log_it_info("Application main loop completed"); return 0; } // Main function int main(int argc, char *argv[]) { int result = EXIT_SUCCESS; printf("=== My First DAP SDK Application ===\n"); printf("Build date: %s %s\n", __DATE__, __TIME__); // Set up signal handlers signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); // Initialize application if (app_init(argc, argv) != 0) { fprintf(stderr, "Application initialization failed\n"); result = EXIT_FAILURE; goto cleanup; } // Run application if (app_run() != 0) { log_it_error("Application execution failed"); result = EXIT_FAILURE; } cleanup: // Cleanup application app_cleanup(); printf("Application terminated with code: %d\n", result); return result; } ``` ### Configuration File Create `app.conf`: ```ini [app] name=MyFirstDAPApp debug=false [logging] level=info file=my_first_app.log [threads] workers=4 [memory] pool_size=67108864 # 64MB ``` ### Updated CMakeLists.txt Update `CMakeLists.txt`: ```cmake cmake_minimum_required(VERSION 3.16) project(MyFirstDAPApp VERSION 1.0.0 LANGUAGES C) # Set C standard set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) # Find DAP SDK find_package(PkgConfig REQUIRED) pkg_check_modules(DAP_SDK REQUIRED dap-sdk) # Include directories include_directories(include) include_directories(${DAP_SDK_INCLUDE_DIRS}) # Compile flags add_compile_options(${DAP_SDK_CFLAGS_OTHER}) add_compile_options(-Wall -Wextra -Werror) # Source files set(SOURCES src/main.c src/app_config.c src/crypto_demo.c ) # Header files set(HEADERS include/app_config.h include/crypto_demo.h ) # Create executable add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS}) # Link libraries target_link_libraries(${PROJECT_NAME} ${DAP_SDK_LIBRARIES}) target_link_directories(${PROJECT_NAME} PRIVATE ${DAP_SDK_LIBRARY_DIRS}) # Debug build options if(CMAKE_BUILD_TYPE STREQUAL "Debug") add_compile_options(-g -O0 -DDAP_DEBUG) endif() # Release build options if(CMAKE_BUILD_TYPE STREQUAL "Release") add_compile_options(-O2 -DNDEBUG) endif() # Installation install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) install(FILES app.conf DESTINATION etc/${PROJECT_NAME}) # Documentation install(FILES README.md DESTINATION share/doc/${PROJECT_NAME}) ``` ## Building and Running ### Build the Enhanced Application ```bash # Clean previous build rm -rf build/* cd build # Configure for debug build cmake -DCMAKE_BUILD_TYPE=Debug .. # Build make # Copy configuration file cp ../app.conf . # Run the application ./MyFirstDAPApp app.conf ``` ### Expected Output ``` === My First DAP SDK Application === Build date: Dec 15 2024 14:30:25 Initializing DAP SDK application... [INFO] Application Configuration: [INFO] App Name: MyFirstDAPApp [INFO] Log File: my_first_app.log [INFO] Log Level: info [INFO] Debug Mode: disabled [INFO] Worker Threads: 4 [INFO] Memory Pool: 67108864 bytes [INFO] Application initialized successfully [INFO] SDK Version: 1.0.0 [INFO] Starting application main loop... [INFO] Starting cryptography demonstrations... [INFO] === Hash Example === [INFO] Message: Hello, DAP SDK World! [INFO] Hash (hex): a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456 [INFO] Hash verification: SUCCESS (hashes match) [INFO] Hash example completed successfully [INFO] === Digital Signature Example === [INFO] Generated key pair for signing [INFO] Message signed successfully [INFO] Signature size: 2420 bytes [INFO] Signature verification: SUCCESS [INFO] Digital signature example completed successfully [INFO] === Encryption Example === [INFO] Generated encryption key [INFO] Plaintext: This is secret data that will be encrypted [INFO] Plaintext size: 42 bytes [INFO] Data encrypted successfully [INFO] Encrypted size: 1088 bytes [INFO] Data decrypted successfully [INFO] Decrypted size: 42 bytes [INFO] Decryption verification: SUCCESS [INFO] Decrypted text: This is secret data that will be encrypted [INFO] Encryption example completed successfully [INFO] All cryptography demonstrations completed. [INFO] Application is running... (Press Ctrl+C to stop) [INFO] Application heartbeat - iteration 10 [INFO] Application heartbeat - iteration 20 [INFO] Application heartbeat - iteration 30 [INFO] Completed 30 iterations, shutting down... [INFO] Application main loop completed [INFO] Cleaning up application... Application cleanup completed. Application terminated with code: 0 ``` ## Key Concepts Demonstrated ### 1. **Proper Initialization** - DAP SDK initialization with `dap_common_init()` - Configuration management and application - Error handling during startup ### 2. **Configuration Management** - Loading configuration from files - Applying configuration to DAP SDK - Default value handling ### 3. **Logging System** - Using DAP SDK logging (`log_it_info`, `log_it_error`, etc.) - Log level configuration - Debug vs. production logging ### 4. **Memory Management** - Using DAP SDK memory functions (`DAP_NEW`, `DAP_DELETE`) - Memory tracking and statistics - Proper cleanup practices ### 5. **Cryptographic Operations** - Hash computation and verification - Digital signatures with key generation - Encryption and decryption - Secure key management ### 6. **Application Lifecycle** - Signal handling for graceful shutdown - Main application loop - Proper cleanup and resource deallocation ### 7. **Error Handling** - Comprehensive error checking - Graceful failure handling - Meaningful error messages ## Next Steps Now that you have a working DAP SDK application, explore these advanced topics: 1. **[[Architecture Overview|Architecture Overview]]** - Deep dive into DAP SDK architecture 2. **[[Development Guide|Development Guide]]** - Advanced development patterns and practices 3. **[[Modules/Module Overview|Module Overview]]** - Explore specific SDK modules: - **[[Modules/Module DAP IO|Module DAP IO]]** - Event-driven programming - **[[Modules/Module DAP Net|Module DAP Net]]** - Network programming - **[[Modules/Module DAP Stream|Module DAP Stream]]** - Data stream processing - **[[Modules/Module DAP Global DB|Module DAP Global DB]]** - Database operations 4. **[[Troubleshooting|Troubleshooting]]** - Common issues and solutions ## Additional Resources - **Example Applications**: Check the SDK's `examples/` directory for more complex applications - **API Documentation**: Complete function reference in **[[Glossary|Glossary]]** - **Community**: Join discussions and get help from the DAP SDK community --- *Last updated: December 2024 | Version: 1.0 | First Application Tutorial for DAP SDK*