| 会员登录 立即注册

打印 上一主题 下一主题

使用开源库 GObject 和 libsoup 提升 C 语言编程能力

[复制链接]
跳转到指定楼层
楼主
3AAA 发表于 2022-10-22 11:03:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
楼主
3AAA
2022-10-22 11:03:48 3686 5 看楼主


开源库 GObject 和 libsoup 做了很多工作,因此你可以专注于使用 C 语言开发神奇的应用。

GLib 对象系统Object System(GObject)是一个为 C 语言提供灵活且可扩展的面向对象框架的库。在这篇文章中,我将使用该库的 2.4 版本进行演示。

GObject 库继承了 ANSI C 标准,拥有一些常见的数据类型,例如:
    gchar:字符型guchar:无符号字符型gunichar:32 位定宽 Unicode 字符型gboolean:布尔型gint8、gint16、gint32、gint64:有符号 8、16、32 和 64 位整数guint8、guint16、guint32、guint64:无符号 8、16、32 和 64 位整数gfloat:IEEE 754 标准单精度浮点数gdouble:IEEE 754 标准双精度浮点数gpointer:泛指针


函数指针


GObject 库还引入了类和接口的类型和对象体系。之所以可以,是因为 ANSI C 语言可以理解函数指针。

你可以这样做来声明函数指针:
void (*my_callback)(gpointer data);
首先,你需要给变量 my_callback赋值:
void my_callback_func(gpointer data){  //do something}my_callback = my_callback_func;
函数指针 my_callback可以这样来调用:
gpointer data;data = g_malloc(512 * sizeof(gint16));my_callback(data);

对象类


GObject基类由 2 个结构(GObject和GObjectClass)组成,你可以继承它们以实现你自己的对象。

你需要在结构体中先嵌入 GObject和GObjectClass:
struct _MyObject{  GObject gobject;  //your fields};struct _MyObjectClass{  GObjectClass gobject;  //your class methods};GType my_object_get_type(void);
对象的实现包含了公有成员。GObject 也提供了私有成员的方法。这实际上是 C 源文件中的一个结构,而不是在头文件。该类通常只包含函数指针。

一个接口不能派生自另一个接口,比如:
struct _MyInterface{  GInterface ginterface;  //your interface methods};
通过调用 g_object_get和g_object_set函数来访问属性。若要获取属性,你必须提供特定类型的返回位置。建议先初始化返回位置:
gchar *strstr = NULL;g_object_get(gobject,  "my-name", &str,  NULL);
或者你想要设置属性:
g_object_set(gobject,  "my-name", "Anderson",  NULL);

libsoup HTTP 库


libsoup项目为 GNOME 提供了 HTTP 客服端和服务端使用的库。它使用 GObjects 和 glib 主循环与集成到 GNOME 应用,并且还具有用于命令行的同步 API。

首先,创建一个特定身份验证回调的 libsoup会话。你也可以使用 cookie。
SoupSession *soup_session;SoupCookieJar *jar;soup_session = soup_session_new_with_options(SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_AUTH_BASIC,  SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_AUTH_DIGEST,  NULL);jar = soup_cookie_jar_text_new("cookies.txt",  FALSE);     soup_session_add_feature(soup_session, jar);g_signal_connect(soup_session, "authenticate",  G_CALLBACK(my_authenticate_callback), NULL);
然后你可以像这样创建一个 HTTP GET 请求:
SoupMessage *msg;SoupMessageHeaders *response_headers;SoupMessageBody *response_body;guint status;GError *error;msg = soup_form_request_new("GET",  "http://127.0.0.1:8080/my-xmlrpc",  NULL);status = soup_session_send_message(soup_session,  msg);response_headers = NULL;response_body = NULL;g_object_get(msg,  "response-headers", &response_headers,  "response-body", &response_body,  NULL);g_message("status %d", status);cookie = NULL;soup_message_headers_iter_init(&iter,response_headers);while(soup_message_headers_iter_next(&iter, &name, &value)){      g_message("%s: %s", name, value);}g_message("%s", response_body->data);if(status == 200){  cookie = soup_cookies_from_response(msg);  while(cookie != NULL){    char *cookie_name;    cookie_name = soup_cookie_get_name(cookie->data);    //parse cookies    cookie = cookie->next;  }}
当网络服务器进行身份认证时,会调用身份认证回调函数。

这是一个函数签名:
#define MY_AUTHENTICATE_LOGIN "my-username"#define MY_AUTHENTICATE_PASSWORD "my-password"void my_authenticate_callback(SoupSession *session,  SoupMessage *msg,  SoupAuth *auth,  gboolean retrying,  gpointer user_data){  g_message("authenticate: ****");  soup_auth_authenticate(auth,                         MY_AUTHENTICATE_LOGIN,                         MY_AUTHENTICATE_PASSWORD);}

一个 libsoup 服务器


想要基础的 HTTP 身份认证能够运行,你需要指定回调函数和服务器上下文路径。然后再添加一个带有另一个回调的处理程序。

下面这个例子展示了在 8080 端口监听任何 IPv4 地址的消息:
SoupServer *soup_server;SoupAuthDomain *auth_domain;GSocket *ip4_socket;GSocketAddress *ip4_address;MyObject *my_object;GError *error;soup_server = soup_server_new(NULL);auth_domain = soup_auth_domain_basic_new(SOUP_AUTH_DOMAIN_REALM, "my-realm",  SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, my_xmlrpc_server_auth_callback,  SOUP_AUTH_DOMAIN_BASIC_AUTH_DATA, my_object,  SOUP_AUTH_DOMAIN_ADD_PATH, "my-xmlrpc",  NULL);soup_server_add_auth_domain(soup_server, auth_domain);soup_server_add_handler(soup_server,  "my-xmlrpc",  my_xmlrpc_server_callback,  my_object,  NULL);ip4_socket = g_socket_new(G_SOCKET_FAMILY_IPV4,  G_SOCKET_TYPE_STREAM,  G_SOCKET_PROTOCOL_TCP,  &error);ip4_address = g_inet_socket_address_new(g_inet_address_new_any(G_SOCKET_FAMILY_IPV4),  8080);error = NULL;g_socket_bind(ip4_socket,  ip4_address,  TRUE,  &error);error = NULL;g_socket_listen(ip4_socket, &error);error = NULL;soup_server_listen_socket(soup_server,  ip4_socket, 0, &error);
示例代码中,有两个回调函数。一个处理身份认证,另一个处理对它的请求。

假设你想要网页服务器允许用户名为 my-username和口令为my-password的凭证登录,并且用一个随机且唯一的用户 ID 字符串设置会话 cookie。
gboolean my_xmlrpc_server_auth_callback(SoupAuthDomain *domain,  SoupMessage *msg,  const char *username,  const char *password,  MyObject *my_object){  if(username == NULL || password == NULL){    return(FALSE);  }  if(!strcmp(username, "my-username") &&     !strcmp(password, "my-password")){    SoupCookie *session_cookie;    GSList *cookie;    gchar *security_token;    cookie = NULL;    security_token = g_uuid_string_random;    session_cookie = soup_cookie_new("my-srv-security-token",      security_token,      "localhost",      "my-xmlrpc",      -1);     cookie = g_slist_prepend(cookie,       session_cookie);       soup_cookies_to_request(cookie,       msg);    return(TRUE);  }  return(FALSE);}
对上下文路径 my-xmlrpc进行处理的函数:
void my_xmlrpc_server_callback(SoupServer *soup_server,  SoupMessage *msg,  const char *path,  GHashTable *query,  SoupClientContext *client,  MyObject *my_object){  GSList *cookie;  cookie = soup_cookies_from_request(msg);  //check cookies}

更加强大的 C 语言


希望我的示例展现了 GObject 和 libsoup 项目给 C 语言带来了真正的提升。像这样在字面意义上扩展 C 语言,可以使 C 语言更易于使用。它们已经为你做了许多工作,这样你可以专注于用 C 语言开发简单、直接的应用程序了。

via: https://opensource.com/article/22/5/libsoup-gobject-c

作者:Jo?l Kr?hemann选题:lkxed译者:Donkey-Hao校对:wxy

本文由 LCTT原创编译,Linux中国荣誉推出
回复

使用道具 举报

沙发
沈老师2017 发表于 2022-10-22 11:04:22 | 只看该作者
沙发
沈老师2017
2022-10-22 11:04:22 看楼主
为什么不直接用cpp
回复 支持 反对

使用道具 举报

板凳
6楼速度来吃翔 发表于 2022-10-22 11:05:33 | 只看该作者
转发了
回复 支持 反对

使用道具 举报

地板
第一快乐人生 发表于 2022-10-22 11:07:20 | 只看该作者
地板
第一快乐人生
2022-10-22 11:07:20 看楼主
转发了
回复 支持 反对

使用道具 举报

5#
暹诺 发表于 2022-10-22 11:07:50 | 只看该作者
5#
暹诺
2022-10-22 11:07:50 看楼主
转发了
回复 支持 反对

使用道具 举报

6#
XUBOTIAN 发表于 2022-10-22 11:08:15 | 只看该作者
6#
XUBOTIAN
2022-10-22 11:08:15 看楼主
如果多出一些图形化库,c语言我要再用100年[呲牙]
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则 返回列表

3AAA 当前离线
白银会员

查看:3686 | 回复:5

关于我们  |   侵权投诉受理  |   联系我们  |   Archiver  |  
免责声明:邳州信息网所有言论只代表发表者个人观点,与本站无关
Copyright © 2009-2025 pzxxw.com 版权所有:邳州金银杏文化传媒有限公司  

苏公网安备 32038202000401号

快速回复 返回顶部 返回列表