DUICUO

オープンソースライブラリ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 データ);

まず、変数​my_callback​に値を割り当てる必要があります。

 void my_callback_func ( gpointer データ)

{

//何かをする

}


my_callback = my_callback_func ;

関数ポインター​my_callback​次のように呼び出すことができます。

 gpointer データ;

データ= g_malloc ( 512 * sizeof ( gint16 ) );

my_callback ( データ);

オブジェクトクラス

​GObject​基本クラスは 2 つの構造体 ( ​GObject​​GObjectClass​ ) で構成されており、これらを継承して独自のオブジェクトを実装できます。

まず、構造体に​GObject​​GObjectClass​を埋め込む必要があります。

 構造体_MyObject

{

GObject gオブジェクト;

//あなたのフィールド

};


構造体_MyObjectClass

{

GObjectClass gobject ;

//クラスメソッド

};


GType my_object_get_type ( void );

オブジェクトの実装にはパブリックメンバーが含まれます。GObject はプライベートメンバーを持つメソッドも提供します。これは実際には C ソースファイル内の構造体であり、ヘッダーファイルには存在しません。クラスには通常、関数ポインタのみが含まれます。

インターフェースは別のインターフェースから派生することはできません。例:

 構造体_MyInterface

{

Gインターフェースgインターフェース;

//インターフェースメソッド

};

プロパティには​g_object_get()​関数と​g_object_set()​関数を呼び出すことでアクセスします。プロパティを取得するには、特定の型の戻り位置を指定する必要があります。戻り位置は最初に初期化することをお勧めします。

 gchar * 文字列


str = NULL ;


g_object_get ( gobject ,

"私の名前"& str

NULL );

または、プロパティを設定することもできます。

 g_object_set ( gobject 、 ...

「私の名前」「アンダーソン」

NULL );

libsoup HTTPライブラリ

​libsoup​プロジェクトは、GNOMEで使用されるHTTPクライアントおよびサーバー用のライブラリを提供します。GNOMEアプリケーションへの統合にはGObjectsとglibメインループを使用し、コマンドラインで使用するための同期APIも備えています。

まず、特定の認証コールバックを使用して​libsoup​セッションを作成します。Cookieを使用することもできます。

 スープセッション* soup_session ;

SoupCookieJar * ;


soup_session = soup_session_new_with_options ( SOUP_SESSION_ADD_FEATURE_BY_TYPESOUP_TYPE_AUTH_BASIC

SOUP_SESSION_ADD_FEATURE_BY_TYPESOUP_TYPE_AUTH_DIGEST

NULL );


jar = soup_cookie_jar_text_new ( "cookies.txt"

間違い);


soup_session_add_feature ( soup_sessionjar );

g_signal_connect ( soup_session"認証"

G_CALLBACK ( my_authenticate_callback )、 NULL );

次に、次のような HTTP GET リクエストを作成します。

 スープメッセージ* メッセージ;

SoupMessageHeaders * レスポンスヘッダー;

スープメッセージ本体* response_body ;

罪悪感のステータス;

GError * エラー;


メッセージ= soup_form_request_new ( "GET"

「http://127.0.0.1:8080/my-xmlrpc」

NULL );


ステータス= soup_session_send_message ( soup_session

メッセージ);


レスポンスヘッダー= NULL ;

レスポンスボディ= NULL ;


g_object_get ( メッセージ

「レスポンスヘッダー」およびresponse_headers

「レスポンスボディ」& response_body

NULL );


g_message ( "ステータス %d " , ステータス);

クッキー= NULL ;

soup_message_headers_iter_init ( & iter ,

レスポンスヘッダー);


soup_message_headers_iter_next ( & iter , & name , & value ) の間、

g_message ( "%s: %s" , 名前, );

}


g_message ( "%s "response_body -> data );

if ( ステータス== 200 ){

クッキー= soup_cookies_from_response ( メッセージ);

while ( クッキー!= NULL ){

char * クッキー名;

cookie_name = soup_cookie_get_name ( クッキー-> データ) ;

//クッキーを解析する

cookie = cookie -> next ;

}

}

Web サーバーは認証を実行するときに、認証コールバック関数を呼び出します。

これは関数シグネチャです:

 #define MY_AUTHENTICATE_LOGIN "ユーザー名"

#define MY_AUTHENTICATE_PASSWORD "私のパスワード"


void my_authenticate_callback ( SoupSession * セッション,

スープメッセージ* メッセージ

SoupAuth * 認証

gboolean 再試行

gpointer ユーザーデータ)

{

g_message ( "認証: ****" );

soup_auth_authenticate ( 認証

MY_AUTHENTICATE_LOGIN

MY_AUTHENTICATE_PASSWORD );

}

libsoupサーバー

ベーシックHTTP認証を機能させるには、コールバック関数とサーバーのコンテキストパスを指定する必要があります。次に、別のコールバックを含むハンドラーを追加する必要があります。

次の例は、ポート 8080 上の任意の IPv4 アドレスからのメッセージをリッスンする方法を示しています。

 スープサーバー* soup_server ;

SoupAuthDomain * 認証ドメイン;

GSocket * ip4_socket ;

GSocketアドレス* ip4_address ;

MyObject * my_object ;

GError * エラー;


soup_server = soup_server_new ( NULL );

auth_domain = soup_auth_domain_basic_new ( SOUP_AUTH_DOMAIN_REALM"my-realm"

SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACKmy_xmlrpc_server_auth_callback

SOUP_AUTH_DOMAIN_BASIC_AUTH_DATAmy_object

SOUP_AUTH_DOMAIN_ADD_PATH"my-xmlrpc"

NULL );


soup_server_add_auth_domain ( soup_serverauth_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

エラー);


ip4_address = g_inet_socket_address_new ( g_inet_address_new_any ( G_SOCKET_FAMILY_IPV4 )、

8080 );

エラー= NULL ;

g_socket_bind ( ip4_socket

ip4_アドレス

真実

エラー);

エラー= NULL ;

g_socket_listen ( ip4_socket& error );


エラー= NULL ;

soup_server_listen_socket ( soup_server

ip4_socket0& エラー);

サンプルコードには2つのコールバック関数があります。1つは認証を処理し、もう1つは認証へのリクエストを処理します。

Web サーバーで、ユーザー名​my-username​とパスワード​my-password​の資格情報を使用してユーザーがログインできるようにし、ランダムで一意のユーザー ID 文字列を含むセッション クッキーを設定するとします。

 gboolean my_xmlrpc_server_auth_callback ( SoupAuthDomain * ドメイン,

スープメッセージ* メッセージ

const char * ユーザー名

const char * パスワード

MyObject * my_object )

{

if ( ユーザー名== NULL || パスワード== NULL ){

( FALSE ) を返します

}


if ( ! strcmp ( ユーザー名, "私のユーザー名" ) &&

! strcmp ( パスワード, "自分のパスワード" )){

スープクッキー* セッションクッキー;

GSList * クッキー;

gchar * セキュリティトークン;

クッキー= NULL ;


セキュリティトークン= g_uuid_string_random ();

session_cookie = soup_cookie_new ( "my-srv-security-token"

セキュリティトークン

「ローカルホスト」

「my-xmlrpc」

- 1 );


クッキー= g_slist_prepend ( クッキー

セッションクッキー);

soup_cookies_to_request ( クッキー

メッセージ);

( TRUE ) を返します

}

( FALSE ) を返します

}

コンテキストパス​my-xmlrpc​を処理する関数:

 void my_xmlrpc_server_callback ( SoupServer * soup_server ,

スープメッセージ* メッセージ

const char * パス

GHashTable * クエリ

SoupClientContext * クライアント

MyObject * my_object )

{

GSList * クッキー;

クッキー= soup_cookies_from_request ( メッセージ);

//クッキーをチェックする

}

より強力なC言語

この例が、GObjectとlibsoupプロジェクトがC言語を真に強化できることを示してくれたことを願っています。このようにC言語を文字通り拡張することで、C言語ははるかに使いやすくなります。これらのプロジェクトは多くの作業を担ってくれ、あなたはC言語でシンプルで分かりやすいアプリケーションの開発に集中できます。