您现在的位置是:网站首页> C/C++

Linux C编程笔记

  • C/C++
  • 2024-09-24
  • 133人已阅读
摘要

Linux C编程笔记


在 linux下C C++的头文件和库文件所在目录

linux下用C操作常规蓝牙和低功耗蓝牙




在 linux下C C++的头文件和库文件所在目录

在Linux系统下,C/C++ 的头文件和库文件通常位于以下几个目录:

头文件:

/usr/include: 这是系统默认的 C/C++ 头文件目录,包含了 C/C++ 标准库以及其他常用库的头文件,例如 stdio.h, iostream, algorithm 等。

/usr/local/include: 这个目录用于存放用户本地安装的软件包的头文件,以便与系统自带的头文件区分开来。

/usr/include/<软件包名称>: 一些软件包会将自己的头文件安装到 /usr/include 目录下的子目录中,例如 /usr/include/python3.8 存放 Python 3.8 的头文件。

/opt/<软件包名称>/include: 一些大型软件包会将自己的头文件安装到 /opt 目录下的子目录中。


库文件:

/usr/lib: 这是系统默认的库文件目录,包含了 C/C++ 标准库以及其他常用库的动态链接库和静态链接库,例如 libc.so, libstdc++.a 等。

/usr/local/lib: 这个目录用于存放用户本地安装的软件包的库文件,以便与系统自带的库文件区分开来。

/usr/lib/<架构>: 一些库文件会根据不同的 CPU 架构存放在不同的目录下,例如 /usr/lib/x86_64-linux-gnu 存放 x86_64 架构的库文件。

/usr/lib/<软件包名称>: 一些软件包会将自己的库文件安装到 /usr/lib 目录下的子目录中。

/opt/<软件包名称>/lib: 一些大型软件包会将自己的库文件安装到 /opt 目录下的子目录中。


需要注意的是:

以上只是一些常见的目录,具体的目录结构可能因 Linux 发行版和软件包的安装方式而有所不同。

可以使用 locate 命令查找特定头文件或库文件的路径,例如 locate stdio.h 或 locate libstdc++.so。

在编译 C/C++ 程序时,可以使用 -I 参数指定头文件目录,使用 -L 参数指定库文件目录,使用 -l 参数指定链接的库文件



linux下用C操作常规蓝牙和低功耗蓝牙

常规蓝牙确保你的系统已经安装了BlueZ库和开发包

sudo apt-get install libbluetooth-dev

然后,这里是一个基本的C程序示例:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/socket.h>

#include <bluetooth/bluetooth.h>

#include <bluetooth/hci.h>

#include <bluetooth/hci_lib.h>

#include <bluetooth/l2cap.h>


#define BLE_ATT_CID 4


int main() {

    int device_id = hci_get_route(NULL);

    int device_handle = 0;

    int sock = 0;

    struct sockaddr_l2 addr = { 0 };

    char dest[18] = "XX:XX:XX:XX:XX:XX";  // 替换为你的BLE设备地址


    // 打开蓝牙设备

    device_handle = hci_open_dev(device_id);

    if (device_handle < 0) {

        perror("Failed to open device");

        exit(1);

    }


    // 创建L2CAP socket

    sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);

    if (sock < 0) {

        perror("Failed to create L2CAP socket");

        exit(1);

    }


    // 设置目标地址

    addr.l2_family = AF_BLUETOOTH;

    addr.l2_cid = htobs(BLE_ATT_CID);

    str2ba(dest, &addr.l2_bdaddr);


    // 连接到BLE设备

    if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {

        perror("Failed to connect");

        close(sock);

        exit(1);

    }


    printf("Connected to %s\n", dest);


    // 发送数据

    char message[] = "Hello, BLE!";

    if (write(sock, message, sizeof(message)) < 0) {

        perror("Failed to send data");

    } else {

        printf("Sent: %s\n", message);

    }


    // 接收数据

    char buffer[1024] = { 0 };

    int bytes_read = read(sock, buffer, sizeof(buffer));

    if (bytes_read > 0) {

        printf("Received: %s\n", buffer);

    } else if (bytes_read < 0) {

        perror("Failed to receive data");

    }


    // 关闭连接

    close(sock);

    return 0;

}

编译和运行这个程序:

gcc -o ble_example ble_example.c -lbluetooth

sudo ./ble_example


注意事项:

你需要将 XX:XX:XX:XX:XX:XX 替换为实际的BLE设备地址。

这个例子使用的是L2CAP协议,这是BLE通信的底层协议。在实际应用中,你可能需要实现更高层的GATT协议。

这个程序需要root权限运行,因为它直接访问蓝牙硬件。

这只是一个基本的例子。实际的BLE通信可能涉及服务发现、特征读写等更复杂的操作。

错误处理在这个例子中很简单,在实际应用中你可能需要更健壮的错误处理机制。

这个例子假设BLE设备已经配对和连接。在实际应用中,你可能需要先进行设备扫描和配对过程。


要深入了解BLE编程,建议查阅BlueZ的官方文档和更多的示例代码。同时,考虑使用一些更高级的库,如 gattlib,它提供了更方便的 API 来处理 BLE 通信。


低功耗蓝牙确保安装了必要的开发库:

sudo apt-get install libglib2.0-dev libgio2.0-cil-dev

然后,这里是一个基本的C程序示例,展示如何扫描BLE设备、连接设备、并读取特征值:

#include <stdio.h>

#include <glib.h>

#include <gio/gio.h>


#define BLUEZ_BUS_NAME "org.bluez"

#define BLUEZ_INTERFACE_ADAPTER1 "org.bluez.Adapter1"

#define BLUEZ_INTERFACE_DEVICE1 "org.bluez.Device1"

#define BLUEZ_INTERFACE_GATTCHAR1 "org.bluez.GattCharacteristic1"


static GMainLoop *main_loop = NULL;


static void on_characteristic_read(GObject *source_object, GAsyncResult *res, gpointer user_data) {

    GVariant *value;

    GError *error = NULL;


    value = g_dbus_proxy_call_finish(G_DBUS_PROXY(source_object), res, &error);

    if (error != NULL) {

        g_print("Error reading characteristic: %s\n", error->message);

        g_error_free(error);

        return;

    }


    GVariant *array;

    g_variant_get(value, "(ay)", &array);

    

    gsize n;

    const guchar *data = g_variant_get_fixed_array(array, &n, sizeof(guchar));

    

    g_print("Characteristic value: ");

    for (gsize i = 0; i < n; i++) {

        g_print("%02x ", data[i]);

    }

    g_print("\n");


    g_variant_unref(value);

    g_main_loop_quit(main_loop);

}


static void on_device_connected(GObject *source_object, GAsyncResult *res, gpointer user_data) {

    GError *error = NULL;

    GVariant *result;


    result = g_dbus_proxy_call_finish(G_DBUS_PROXY(source_object), res, &error);

    if (error != NULL) {

        g_print("Error connecting to device: %s\n", error->message);

        g_error_free(error);

        return;

    }


    g_print("Connected to device\n");


    // 这里应该实现服务和特征发现

    // 为了简化,我们假设已知特征的路径

    const gchar *char_path = "/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service000a/char000b";

    

    GDBusProxy *char_proxy = g_dbus_proxy_new_for_bus_sync(

        G_BUS_TYPE_SYSTEM,

        G_DBUS_PROXY_FLAGS_NONE,

        NULL,

        BLUEZ_BUS_NAME,

        char_path,

        BLUEZ_INTERFACE_GATTCHAR1,

        NULL,

        &error

    );


    if (error != NULL) {

        g_print("Error creating characteristic proxy: %s\n", error->message);

        g_error_free(error);

        return;

    }


    g_dbus_proxy_call(

        char_proxy,

        "ReadValue",

        g_variant_new("(a{sv})", NULL),

        G_DBUS_CALL_FLAGS_NONE,

        -1,

        NULL,

        on_characteristic_read,

        NULL

    );


    g_object_unref(char_proxy);

    g_variant_unref(result);

}


static void on_device_found(GDBusProxy *proxy, GVariant *changed_properties, GStrv invalidated_properties, gpointer user_data) {

    GVariantIter *iter;

    const gchar *key;

    GVariant *value;

    

    g_variant_get(changed_properties, "a{sv}", &iter);

    while (g_variant_iter_loop(iter, "{&sv}", &key, &value)) {

        if (g_strcmp0(key, "Address") == 0) {

            const gchar *address = g_variant_get_string(value, NULL);

            g_print("Found device: %s\n", address);

            

            // 连接到设备

            g_dbus_proxy_call(

                proxy,

                "Connect",

                NULL,

                G_DBUS_CALL_FLAGS_NONE,

                -1,

                NULL,

                on_device_connected,

                NULL

            );

            

            break;

        }

    }

    g_variant_iter_free(iter);

}


int main(void) {

    GError *error = NULL;

    GDBusProxy *adapter_proxy;


    main_loop = g_main_loop_new(NULL, FALSE);


    adapter_proxy = g_dbus_proxy_new_for_bus_sync(

        G_BUS_TYPE_SYSTEM,

        G_DBUS_PROXY_FLAGS_NONE,

        NULL,

        BLUEZ_BUS_NAME,

        "/org/bluez/hci0",

        BLUEZ_INTERFACE_ADAPTER1,

        NULL,

        &error

    );


    if (error != NULL) {

        g_print("Error creating adapter proxy: %s\n", error->message);

        g_error_free(error);

        return 1;

    }


    g_signal_connect(adapter_proxy, "g-properties-changed", G_CALLBACK(on_device_found), NULL);


    // 开始扫描

    g_dbus_proxy_call_sync(

        adapter_proxy,

        "StartDiscovery",

        NULL,

        G_DBUS_CALL_FLAGS_NONE,

        -1,

        NULL,

        &error

    );


    if (error != NULL) {

        g_print("Error starting discovery: %s\n", error->message);

        g_error_free(error);

        return 1;

    }


    g_main_loop_run(main_loop);


    g_object_unref(adapter_proxy);

    g_main_loop_unref(main_loop);


    return 0;

}

编译和运行这个程序:

gcc -o ble_example ble_example.c `pkg-config --cflags --libs glib-2.0 gio-2.0` -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include

sudo ./ble_example


注意事项:

这个例子展示了如何扫描BLE设备、连接到设备、并读取一个特征值。你需要替换 XX_XX_XX_XX_XX_XX 为实际的设备地址,并修改特征路径以匹配你的设备。

这个程序需要root权限运行,因为它需要访问系统的D-Bus。

这只是一个基本的例子。实际的BLE应用可能需要更复杂的服务和特征发现过程。

错误处理在这个例子中很简单,在实际应用中你可能需要更健壮的错误处理机制。

这个例子使用了同步和异步的D-Bus调用。在实际应用中,你可能需要更多地使用异步调用以提高性能。

为了简化,这个例子没有实现写入特征或订阅通知的功能。这些功能可以用类似的方式实现。


要深入了解Linux下的BLE编程,建议查阅BlueZ的官方文档和D-Bus规范。同时,考虑使用一些更高级的库,如 bluez-dbus,它提供了更方便的API来处理BLE通信。















上一篇:VC相关信息

Top