## 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*