g_strdup_printf

本文介绍了g_strdup_printf函数,它是glibc中的一个类似于sprintf的安全替代方案。该函数会自动计算所需的缓冲区大小并分配内存来存储格式化后的字符串,返回的字符串需要使用g_free释放。

g_strdup_printf是glibc下的函数

g_strdup_printf是一个和sprintf差不多的函数,但是 g_strdup_printf更安全和智能,并且在释放的时候也只能用 g_free (至于为什么更安全,我也想知道,有知道的请留言告诉我)  .  g_strdup_printf为分析一段buffer(也不理解)


例子:

#include <stdio.h>
#include <glib.h>

int main() {
    char *a = "aaaaaaaaaaa";
    char *t = g_strdup_printf ("%s", a);
    printf("%s", t);
}


g_strdup_printf ()

gchar *
g_strdup_printf (const gchar *format,
                 ...);

Similar to the standard C sprintf() function but safer, since it calculates the maximum space required and allocates memory to hold the result. The returned string should be freed with g_free() when no longer needed.

Parameters

format

a standard printf() format string, but notice string precision pitfalls

 

...

the parameters to insert into the format string

 
Returns

a newly-allocated string holding the result


#include <glib.h> #include <gio/gio.h> #include <stdio.h> #include <string.h> #define BLUEZ_SERVICE "org.bluez" #define AGENT_INTERFACE "org.bluez.Agent1" #define AGENT_MANAGER_INTERFACE "org.bluez.AgentManager1" #define DEVICE_INTERFACE "org.bluez.Device1" #define AGENT_PATH "/org/bluez/example/agent" static GMainLoop *main_loop = NULL; static GDBusConnection *connection = NULL; static gchar *device_address = NULL; static gchar *adapter = "hci0"; // 移到全局以解决初始化问题 /* 兼容低版本GLib,实现字符串替换函数 */ static gchar *str_replace(const gchar *string, const gchar *search, const gchar *replace) { gchar *result = g_strdup(string); gchar *temp; gint search_len = strlen(search); gint replace_len = strlen(replace); while ((temp = strstr(result, search)) != NULL) { // 计算新字符串长度 gint result_len = strlen(result); gint new_len = result_len - search_len + replace_len + 1; // 分配新内存 gchar *new_result = g_malloc(new_len); // 复制前面部分 gint prefix_len = temp - result; strncpy(new_result, result, prefix_len); new_result[prefix_len] = '\0'; // 拼接替换字符串和剩余部分 strcat(new_result, replace); strcat(new_result, temp + search_len); // 更新结果并释放旧内存 g_free(result); result = new_result; } return result; } /* 配对代理方法实现 */ static void agent_release(GDBusConnection *conn, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { g_print("Agent released\n"); g_dbus_method_invocation_return_value(invocation, NULL); } static void agent_request_pin_code(GDBusConnection *conn, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { gchar *device_path; g_variant_get(parameters, "(o)", &device_path); g_print("Requesting PIN code for device: %s\n", device_path); g_print("Enter PIN code: "); char pin[17]; fgets(pin, sizeof(pin), stdin); pin[strcspn(pin, "\n")] = '\0'; // 移除换行符 g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", pin)); g_free(device_path); } static void agent_request_confirmation(GDBusConnection *conn, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { gchar *device_path; guint32 passkey; g_variant_get(parameters, "(ou)", &device_path, &passkey); g_print("Confirm pairing with device %s (passkey: %06d)? (y/n) ", device_path, passkey); char response[10]; fgets(response, sizeof(response), stdin); if (response[0] == 'y' || response[0] == 'Y') { g_dbus_method_invocation_return_value(invocation, NULL); } else { GError *error = g_error_new(G_IO_ERROR, G_IO_ERROR_CANCELLED, "User rejected pairing"); g_dbus_method_invocation_return_error(invocation, error->domain, error->code, "%s", error->message); g_error_free(error); } g_free(device_path); } static void agent_cancel(GDBusConnection *conn, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { g_print("Pairing cancelled\n"); g_dbus_method_invocation_return_value(invocation, NULL); } /* 方法调用处理函数 */ static void agent_method_call(GDBusConnection *conn, const gchar *sender, const gchar *obj_path, const gchar *iface_name, const gchar *method_name, GVariant *params, GDBusMethodInvocation *invoc, gpointer udata) { if (g_strcmp0(method_name, "Release") == 0) { agent_release(conn, sender, obj_path, iface_name, method_name, params, invoc, udata); } else if (g_strcmp0(method_name, "RequestPinCode") == 0) { agent_request_pin_code(conn, sender, obj_path, iface_name, method_name, params, invoc, udata); } else if (g_strcmp0(method_name, "RequestConfirmation") == 0) { agent_request_confirmation(conn, sender, obj_path, iface_name, method_name, params, invoc, udata); } else if (g_strcmp0(method_name, "Cancel") == 0) { agent_cancel(conn, sender, obj_path, iface_name, method_name, params, invoc, udata); } else { g_dbus_method_invocation_return_error(invoc, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Unknown method %s", method_name); } } /* 定义Agent接口的方法表 */ static const GDBusInterfaceVTable agent_vtable = { .method_call = agent_method_call, .get_property = NULL, .set_property = NULL }; /* 注册Agent到BlueZ */ static gboolean register_agent(GDBusConnection *conn) { GError *error = NULL; GVariant *result; result = g_dbus_connection_call_sync(conn, BLUEZ_SERVICE, "/org/bluez", AGENT_MANAGER_INTERFACE, "RegisterAgent", g_variant_new("(os)", AGENT_PATH, "DisplayYesNo"), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error != NULL) { g_printerr("Failed to register agent: %s\n", error->message); g_error_free(error); return FALSE; } g_variant_unref(result); /* 设置为默认Agent */ result = g_dbus_connection_call_sync(conn, BLUEZ_SERVICE, "/org/bluez", AGENT_MANAGER_INTERFACE, "RequestDefaultAgent", g_variant_new("(o)", AGENT_PATH), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error != NULL) { g_printerr("Failed to set default agent: %s\n", error->message); g_error_free(error); return FALSE; } g_variant_unref(result); g_print("Agent registered successfully\n"); return TRUE; } /* 开始与指定设备配对 */ static gboolean pair_device(GDBusConnection *conn, const gchar *adapter_path) { gchar *device_path; GError *error = NULL; GVariant *result; gchar *address_copy, *replaced_address; if (!device_address) { g_printerr("No device address specified\n"); return FALSE; } /* 使用自定义的字符串替换函数 */ address_copy = g_strdup(device_address); replaced_address = str_replace(address_copy, ":", "_"); device_path = g_strdup_printf("%s/dev_%s", adapter_path, replaced_address); g_print("Pairing with device: %s\n", device_path); /* 调用配对方法 */ result = g_dbus_connection_call_sync(conn, BLUEZ_SERVICE, device_path, DEVICE_INTERFACE, "Pair", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, 60000, // 60秒超时 NULL, &error); if (error != NULL) { g_printerr("Pairing failed: %s\n", error->message); g_error_free(error); g_free(device_path); g_free(replaced_address); g_free(address_copy); return FALSE; } g_print("Pairing successful\n"); /* 绑定设备(保存配对信息) */ g_dbus_connection_call_sync(conn, BLUEZ_SERVICE, device_path, DEVICE_INTERFACE, "Connect", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, 60000, NULL, &error); if (error != NULL) { g_printerr("Connection failed: %s\n", error->message); g_error_free(error); g_free(device_path); g_free(replaced_address); g_free(address_copy); g_variant_unref(result); return FALSE; } g_print("Device connected successfully\n"); g_free(device_path); g_free(replaced_address); g_free(address_copy); g_variant_unref(result); return TRUE; } /* 设备属性变化信号处理 */ static void device_property_changed(GDBusConnection *conn, const gchar *sender, const gchar *path, const gchar *interface, const gchar *signal, GVariant *params, gpointer user_data) { GVariantIter *properties; const gchar *iface; gchar *key; GVariant *value; g_variant_get(params, "(&sa{sv}as)", &iface, &properties, NULL); if (g_strcmp0(iface, DEVICE_INTERFACE) != 0) return; while (g_variant_iter_next(properties, "{&sv}", &key, &value)) { if (g_strcmp0(key, "Paired") == 0) { gboolean paired = g_variant_get_boolean(value); g_print("Device paired status: %s\n", paired ? "Paired" : "Not paired"); if (paired) { g_print("Pairing completed successfully\n"); g_main_loop_quit(main_loop); } } else if (g_strcmp0(key, "Connected") == 0) { gboolean connected = g_variant_get_boolean(value); g_print("Device connection status: %s\n", connected ? "Connected" : "Disconnected"); } g_variant_unref(value); } g_variant_iter_free(properties); } static void usage(const gchar *progname) { g_print("Usage: %s [OPTIONS] <device_address>\n", progname); g_print("Options:\n"); g_print(" -a, --adapter=ADAPTER Use specified adapter (default: hci0)\n"); g_print(" -h, --help Show this help message\n"); } int main(int argc, char *argv[]) { GError *error = NULL; guint agent_reg_id; guint signal_id; gchar *adapter_path; /* 解析命令行参数 - 修复初始化问题 */ static const GOptionEntry options[] = { {"adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter, "Use specified adapter", "ADAPTER"}, {"help", 'h', 0, G_OPTION_ARG_NONE, NULL, "Show help", NULL}, {NULL} }; GOptionContext *context = g_option_context_new("- BlueZ pairing example"); g_option_context_add_main_entries(context, options, NULL); if (!g_option_context_parse(context, &argc, &argv, &error)) { g_printerr("Option parsing failed: %s\n", error->message); g_error_free(error); return 1; } g_option_context_free(context); if (argc < 2) { usage(argv[0]); return 1; } device_address = argv[1]; adapter_path = g_strdup_printf("/org/bluez/%s", adapter); /* 条件调用g_type_init,兼容不同版本GLib */ #if !GLIB_CHECK_VERSION(2,36,0) g_type_init(); #endif /* 获取系统总线连接 */ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); if (!connection) { g_printerr("Failed to connect to system bus: %s\n", error->message); g_error_free(error); return 1; } /* 注册Agent接口 */ agent_reg_id = g_dbus_connection_register_object(connection, AGENT_PATH, g_dbus_node_info_new_for_xml( "<node>" " <interface name='org.bluez.Agent1'>" " <method name='Release'/>" " <method name='RequestPinCode'>" " <arg type='o' name='device' direction='in'/>" " <arg type='s' name='pincode' direction='out'/>" " </method>" " <method name='RequestConfirmation'>" " <arg type='o' name='device' direction='in'/>" " <arg type='u' name='passkey' direction='in'/>" " </method>" " <method name='Cancel'/>" " </interface>" "</node>", NULL)->interfaces[0], &agent_vtable, NULL, NULL, &error); if (error != NULL) { g_printerr("Failed to register agent object: %s\n", error->message); g_error_free(error); return 1; } /* 注册设备属性变化信号监听 */ signal_id = g_dbus_connection_signal_subscribe(connection, BLUEZ_SERVICE, "org.freedesktop.DBus.Properties", "PropertiesChanged", NULL, DEVICE_INTERFACE, G_DBUS_SIGNAL_FLAGS_NONE, device_property_changed, NULL, NULL); /* 注册Agent到BlueZ */ if (!register_agent(connection)) { g_dbus_connection_unregister_object(connection, agent_reg_id); g_object_unref(connection); return 1; } /* 开始配对过程 */ if (!pair_device(connection, adapter_path)) { g_dbus_connection_signal_unsubscribe(connection, signal_id); g_dbus_connection_unregister_object(connection, agent_reg_id); g_object_unref(connection); return 1; } /* 启动主循环 */ main_loop = g_main_loop_new(NULL, FALSE); g_print("Waiting for pairing to complete...\n"); g_main_loop_run(main_loop); /* 清理资源 */ g_main_loop_unref(main_loop); g_dbus_connection_signal_unsubscribe(connection, signal_id); g_dbus_connection_unregister_object(connection, agent_reg_id); g_object_unref(connection); g_free(adapter_path); return 0; }
最新发布
08-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值