• ベストアンサー

システムコールと標準ライブラリの正しい使い方を教えて下さい

システムコールって何でしょうか。 C言語初心者なので、変な質問だったら、すみません。 システムコールと標準ライブラリにおける、関数の違いを教えて頂けませんでしょうか。 例えばファイル入出力で用いる openとfopenは何が違うのでしょうか? 私はそもそも、システムコールというものが判っていない状態です。 いつも標準ライブラリを参考にしていたものですから・・。 更に似た使い方をすると思いますが、使える範囲等どちらが広いのでしょうか。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • terra5
  • ベストアンサー率34% (574/1662)
回答No.3

システムコールは本来はOSが提供する機能をほぼそのまま呼び出すものです。OSによっては呼び方が違うこともあります(スーパバイザコールとか) ほぼ、と書いたのは実際には各言語から直接呼び出せるとは限らないからです。 だいたいはアセンブラレベルで定義されてます。 OSの機能そのままなので、OSによっては全く違いますし、該当する機能がない場合もあります。 openは本来 unix系のOSが提供する機能そのものです。 ですので、同じunix系であっても細かい違いがあります。 MS-DOS等でもopenはありますが、これは本来システムコールではなく、unix系OSのシステムコール互換ライブラリになります。 これに対して fopenはC言語レベルで共通に使えるように作られたサブルーチンで、 基本的にOS等に依存しないで使えるように作られたものです。 中身は勿論OSによって違ってきますが、使い方はほぼ同じです。 厳密にはパラメタの内容に違いがありますし、 動きもOSに依存する違いが出てくる場合もありますが。 C言語で書く場合は標準ライブラリのみ使用していると、OS等が違ってもほぼそのまま動くプログラムを書くことができますが、 システムコールを使った場合はまずOSが異なった場合は、 たいていなんらかの書き換えが必要になります。 但し、標準ライブラリだと共通に使うことが目的なため、用途によっては機能的に足らない場合もあります。 単純に使える範囲では標準ライブラリの方が広いですね。 機能としては似ている物もありますが、通常は使い方は区別する方がいいですね。 特に問題、不自由なければ標準ライブラリを使うことをおすすめします。 プログラムいろいろ作っていくとシステムコールでなければできない場合がありますから、 システムコールはその時に使えばいいでしょう。 例えば私はWindowsのプログラムを書く場合でも、通常 fopen等を使いますが、 必要な場合はFileCreate等(WIN32API,システムコールと同等)を使います。

その他の回答 (3)

  • ranx
  • ベストアンサー率24% (357/1463)
回答No.4

既に出ている回答で良いと思うのですが、他の回答者の方々が忘れておられる かもしれない側面について補足しておきます。 UNIXは、タイムシェアリングシステム、すなわち1台のコンピュータを複数の 人が共有して使うやり方を想定して作られました。コンピュータを扱う人と プログラマが同義語だった時代です。ある人の作ったプログラムが他の人の プログラムを妨害しては困ります。ですので、共通の資源の管理、ディスクの 入出力とかプロセスの生成といったことは特権モードで一括して行うように しました。ユーザーのプログラムは、この特権モードのルーチンを呼び出す ことによって資源を割り当ててもらい、必要な処理を行います。これが システムコールです。 一方、多くのプログラマが共通に使うルーチンだけれども、必ずしも特権を 必要としない処理もあります。数学の関数の計算などが代表的なものです。 入出力についても、物理的な入出力自体は特権が必要であっても、それに 関する処理、例えばバッファリングですとか出力文字列のフォーマッティング などは特権を必要としません。ですので、これらの処理は非特権モードで 実行し、必要に応じて共通ルーチンの中からシステムコールを行うように なっています。これが標準ライブラリのわけです。

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.2

システムコールと標準ライブラリの違いは、プラットフォームによって話が違ってくるので、一概に「こう」とは言いきれないのですが。 元々、C言語は unix で使われていたので、まずはその部分から。 unix 上のCでは、システムコール関数を呼び出すと、渡されたパラメータをそのままカーネルシステムに渡し、結果が返って来るまで待って、アプリケーションに結果を返します。 ところが、unix には BSD 系の OS と SYSTEM-V 系の OS と2種類の体系があり、また、同じ系列の unix でも機種による違い(方言)があり、パラメータや結果の返り方が微妙に違っているシステムコールがあります。 そうなると、機種ごとの微妙な違いを吸収する為の「標準的な何か」が必要になって来ます。 そこで用意されたのが、標準ライブラリです。 標準ライブラリは、unix の体系ごと、各機種ごとに合わせた物が用意され、出入り口のインターフェースが統一されています。OS の仕様の違いはライブラリ関数内で吸収されます。 そうする事により、システムコールを使わず標準ライブラリのみ使っていれば、OS の仕様が微妙に異なるシステムに移植する作業が安易になります。 (実行ファイル作成時に、機種ごとに用意されたライブラリファイルのどれを使うか指定するだけで済みます) ただ、標準ライブラリのみを使っていると、移植が安易になる反面、OS の仕様の違いを吸収する為のオーバーヘッドがあり、速度的に遅くなる、実行コードが大きくなると言う短所があります。 その為、速度重視、コードサイズ重視で設計する場合や、やりたい事が標準ライブラリに無くシステムコールするしか無い場合もあり、システムコール関数を使わずに済ます事は出来ません。 そういった経緯で、C言語にはシステムコール関数と標準ライブラリ関数の両方が存在します。 で、時代は unix から MS-DOS へと移って行きます。そして、C言語のシステムコール関数と標準ライブラリ関数の意味合いも、OS の違いと共に移り変わって行きます。 unix と MS-DOS では、カーネルシステムそのものがまったく違います。でも、unix 上で開発したソースコード資産を無駄にはしたくありません。 そこで、unix 用のシステムコール関数と同じような動きをする関数が MS-DOS 用のライブラリとして用意され、同じく、標準ライブラリ関数も用意されました。そうすれば、unix から MS-DOS への移植が容易になりますから。 つまり、OS の違いをシステムコール関数内で吸収してしまった訳です。標準ライブラリ関数が unix の微妙な違いを関数内で吸収したのと同じような事をした訳ですね。 (ファイルの「テキスト」「バイナリ」の概念も、ここで取り入れられました。unix と MS-DOS の「改行コード」の違いを吸収する為、テキストファイルを読む場合は CR+LF を LF に、書く場合は LF を CR+LF に変換する必要があったのです。アプリケーションは「改行は LF のみ」として作られている訳ですから) そういった訳で、MS-DOS 用のC言語では、システムコール関数と標準ライブラリ関数の違いが曖昧になりました。どちらも「OS の違いを関数内で吸収し、インターフェースを統一している」訳ですから。 そんな訳で「システムコール(関数)と標準ライブラリ(関数)における、関数の違いって何?」と言う疑問が湧くのも当然です。 (Windows のコンソールアプリケーションを含む)MS-DOS 系では、パラメータが違うだけで、内部でやっている事は同じような事なのですから。 「使える範囲等どちらが広いか」ですが、ここまで読んでお判りかと思いますが、標準ライブラリ関数の方が機種依存性は低く広範囲に使えます。但し、痒い所に手は届きません(汎用性を重視している為、最大公約数的な事しか出来ません) で、時代は MS-DOS から更に Windows へと進む訳ですが、ここで話は一変してしまいます。そう、GUIの登場です(unix にもGUIはあるのですが、ここでは割愛) GUIの登場により、コンソールが使われなくなり、その変わりにウィンドゥ、マウスなど、グラフィカルな部分を扱う関数や、プロセス制御を行ったり、イベントを処理する必要が出て来ました。 その為、今までのシステムコール関数と標準ライブラリ関数は忘れ去られ、変わりにAPI関数が登場しました。 C言語そのものも、GUIを扱いやすくする為、クラスの概念を導入し、クラスの階層化を行ってC++に進化して来ました。 以上、長文になりましたが、回答になっているでしょうか?

  • shige_70
  • ベストアンサー率17% (168/946)
回答No.1

システムコールはunixの世界で用いられるものです。 unix以外の環境でもunixシステムコール互換のライブラリが用意されている場合が多いと思いますが、、、 システムコールは、OSの機能を直接さわるものですので、OSによって異なる部分があったりします。標準ライブラリは、環境による差異を吸収し、どんな場合でも同じように使えるように、かつ使いやすいように設計されています。 初心者とのことですので、どうしても必要でなければシステムコールは使わずに、なるべく準ライブラリをお使いになることをおすすめします。

関連するQ&A

  • 標準ライブラリと命令セットの違い

    標準ライブラリ関数と命令セットの違いが分かりません。そもそも標準ライブラリ関数と命令セットの意味が分からないのですが。どこかよいホームページはございませんでしょうか?

  • 標準ライブラリー関数を使用せずに文字出力

    はじめまして、C言語初心者です。 研修で、C言語を学ぶことになったのですが研修先から頂いた練習問題で「練習のため標準ライブラリー関数は使わない」で文字列を連結するための関数を作ることになったのですが、標準ライブラリー関数を使用せずに文字出力はできるのですか??

  • 標準ライブラリ関数

    C言語の勉強を始めたばかりです。 標準ライブラリ関数というのがたくさんありますが、実際のソースをのせているサイトってありませんか?たとえばstrcmpを使わずにアルファベット順に並べ替えるプログラムを作ってみたいのですが。お願いします。

  • Windowsのシステムコール呼び出し

    アセンブラでシステムコールを呼び出したいのですが、 Linuxとかだとシステムコールの一覧みたいのが載ってるのですが、 Windowsのシステムコールの一覧みたいのが見つかりません。 一覧が載っているようなサイトってありませんか?? とりあえずLinuxの11番(C言語で言うexecv関数)みたいのが使いたいのですが。。。

  • 標準ライブラリ関数の自作について質問です。

    C言語初心者の学生です。 標準ライブラリ関数のstrncpyと同じ機能の関数を自作でつくる場合どのようにすれば良いでしょうか。 mystrncpy(char *s1,char *s2,int n) { } かっこの間を埋める形でお願いします。 同じようにstrncat、strnchr、strnstrも答えていただけると幸いです。 すべてではなく4つのうち1つからでも結構ですのでよろしくお願いいたします。

  • Solarisの実装メモリ容量を得るシステムコール(ライブラリコール)

    Solarisではコマンドラインでは、prtconfをすると実装メモリ容量を得ることが出来ますが、これと同じ情報(実装メモリ容量だけでいいです)をCやC++のプログラムから、システム(ライブラリ)コールを呼ぶことで得る方法を知っている方教えてください。 ちなみに、Linuxでは、/proc/meminfo の中に実装メモリ容量が書かれているので、このファイルをopen / read / close してやれば解決するのですが....Solarisにはどうもこういった便利なファイルが見当たりません....。

  • ライブラリのリンクについて。

    ふと、疑問に思ったので質問させてもらいます。 C言語などでプログラムを作る時、ライブラリをリンクさせて使うと思いますが、その場合プログラムを実行させた場合メモリー上ではどうなるのか教えた貰いたいです。 例えばprintf関数を使う場合その命令そのものがプログラムに組み込まれてメモリーに読み込まれているのかということです。 前にどこかで読んだ記憶があるのですが、いろいろなところから呼び出される標準的なものはシステムで一箇所にありそれを使うなどということがあったような無かったような記憶があやふやですが見た覚えがあるので気になってしまいました。 あとライブラリなどから一つだけ関数を使う場合、使わない他の関数などもメモリーに読み込まれていたりするのでしょうか? よく使う自分で作った関数を一つのファイルにまとめ、それを定義したヘッダーファイルをincludeした場合も同様で使わないほかの関数はどうなるのでしょうか?

  • プログラミング言語C第2版 カーニハンリッチー

    上記のタイトルの参考書で今、C言語の勉強をしています。 第8章のfopenを低水準入出力関数で実装する という項目に取り組んでいるのですが 参考書通りにコーディングしても _iod や OPEN_MAX が見つからないみたいなコメントが出てきて コンパイルができません。 どのヘッダファイルをインクルードすれば良いのでしょうか?

  • C言語のライブラリ

    C言語の初心者でただいま勉強中です。 今ちょうど、関数のところでライブラリについて 勉強しているのですが ライブラリのソースがどうなっているのか気になっております。 どうにかしてライブラリのソースを見る方法はないでしょうか?

  • Linuxで、標準Cライブラリが読み込まれず、C言語プログラミングができません・・・

    僕の問題はタイトルの通りで、標準Cライブラリが読み込まれていないようで、C言語プログラミングができません。 ubuntuのオフィシャルから日本語ローカライズドDesktopCDをダウンロードして、空のHDDにインストールしました。 ですが、gnome-terminalからccコマンドでプログラムをコンパイルしても、標準Cライブラリにあるはずの<stdio.h>が認識されず、続くprinft関数も読んでくれません。 これはどうしてでしょうか?LinuxはデフォルトでCやらJAVAやらのプログラミングの環境が整っているものだと思っていたので、戸惑っています。何か、セットアップが必要なのでしょうか。 ちなみに、gccでも、標準ライブラリは読み込まれませんでした。

専門家に質問してみよう