「技術」カテゴリーアーカイブ

【C言語】コンパイルとリンクとビルドの話

昔、仕事現場で、

「リンクって何ですか?」

って聞いてきた若者がいたので、

ここできちんと説明した方が良いのかなと。

まず、コンピュータに命令を出すには、0と1で記述された「機械語」で命令を出さなければなりません。

機械語でなければコンピュータは理解できないのです。

なので、記述したソースコードを実行するには、ソースコードを機械語に変換する必要があります。

ソースコードを機械語に変換する処理を「コンパイル」といいます。

C言語の場合、ソースファイル毎にコンパイルを行い、オブジェクトファイルという形で機械語に変換します。

しかし、このままでは機械語の命令がソースファイル毎に分断されている状態なので、このままでもコンピューターに実行させることはできません。

そこで、実行に必要なファイルを1つに結合する「リンク」という作業が必要になります。

C言語の場合、ソースファイル毎に変換されたオブジェクトファイルと実行に必要なライブラリファイルを1つにまとめて実行形式のファイルに結合します。

一般的に「ビルド」と呼んでいるのは、この「コンパイル」と「リンク」を一括して行う作業をいいます。

次回は変数について説明しようと思います。

【C言語】最初のプログラム

前々からやろうと思っていた、プログラミングをレクチャーする記事を書きたかった。

なので、まずはC言語でやってみようと思います。

C言語はアプリケーションの世界では余り使われていませんが、ファームウェアやOSなどのハードに近い処理を行うところで、現在でも現役で使用されています。

それにC言語で身につけた知識は他の言語にも通ずる所が沢山ありますので、よりプログラミングの知識を身につけたいと思っているのなら、学んでいて損は無いです。

それではやっていきましょう。

使用するツールはVisual Studio 2017を使用します。

事前準備として、C++プロジェクトが使用できるようにします。

メニューから「ツール」→「ツールと機能を取得」を選択し、「C++によるデスクトップ開発」にチェックを入れます。

次にメニューから「ファイル」→「新規作成」→「プロジェクト」を選択して「Visual C++」のWindowsコンソールアプリケーションを選択します。

※「Windowsデスクトップアプリケーション」は何かとハードルが高いので、とりあえず今回は触れません。

そうすると、以下のようなソースコードが表示されます。

実は、この状態ですでにプログラムが出来上がっています。

実際に実行してみましょう。

メニューから「デバッグ」→「デバッグの開始」を選択してください。

こんな感じに表示されるはずです。

しかし、このコードはC++のコードで記述されています。

ですので、これをC言語のコードに書き換えます。

書き換える場所は以下の二箇所

書き換えたら先ほどと同じようにデバッグの開始をしてみてください。先ほどと同じ結果になるはずです。

それではこのコードの解説を行います。

#include <stdio.h>

stdio.hは標準入出力ライブラリを使用可能にするヘッダーファイルを適用する、という意味です。これを書かなければ、次に説明する「printf()関数」が使用できません。

標準入出力というのは「画面のコンソール」を差します。コンソール画面からキーボードの入力やコンソールに文字列を表示する、といった一連の機能をstdioライブラリで提供しています。

printf("Hello World!\n");

printf()は標準出力に文字列を出力する関数です。表示する文字列は()の中の「”」で括られた文字列です。

最後の「¥n」は改行を表しています。

次回はコンパイル、リンク、ビルドの話をしようと思います。

Alexaで遊ぼう、時間になるとしゃべってくれるようにする

この機能って最初からあったっけ??

指定した時間になると自動的にAlexaさんが動くように指定することができます。

例えば、朝8時になるとその日のゴミを教えてくれるように設定する

あらかじめグーグルカレンダーにゴミのスケジュールを入力しておき、Alexaアプリからグーグルカレンダーに連携させる。

そして、朝8時になったらその日のスケジュールをしゃべるように設定する。

これが意外と便利。

ゴミの日スキルもありますが、それはいちいちAlexaに話しかけないと作動しないので、なにもしなくても知らせてくれるのは便利です。

時間になったら特定のメッセージを話すこともできます。

例えば、13時になったら薬を飲むようにしゃべってくれる、とかもできます。

とにもかくにも、Alexaさんから動いてくれるのが便利なんですよ!

工夫次第ではもっと便利な使用方法があるのかも!

Alexaさんで遊ぼう。ラジコでの再生について

よく、Alexaのradiko.jpアプリで

「ラジコで○○を再生しますか?」

と聞かれるの、なんとかしてくれ、「はい」って言っても聞き取ってくれない、

というレビューをよく目にしますが。

自分、気がつきました。

正しい放送局名を言わないと、Alexaさんは聞き返します。

例えば、

「アレクサ、STVを再生して」

では、Alexaさんは

「radikoでSTVラジオを再生しますか?」

と聞かれます。

しかし、

「アレクサ、STVラジオを再生して」

と言えば、すぐにradiko.jpでSTVラジオを流してくれます。

radikoで再生する場合は、放送局名を正式名称で呼びましょう。

Alexaさんで遊ぼう。フラッシュニュースを追加する。

Alexaさんには

「アレクサ、今日のニュースは?」

と話しかけると、フラッシュニュースを読み上げてくれます。

しかし、初期状態では、日テレニュース、NHKニュース、天気予報しか読み上げてくれません。

このフラッシュニュースにもスキルを追加して読み上げてくれるニュースを増やすことができます。

ニューススキルも沢山ありますが、中にはしょーもないようなニュースばかりのスキルもあるので、いろいろ試しながら都度カスタマイズして、自分好みのAlexa設定に調整する必要があります。

ニューススキル自体は本当に沢山あるので、いろいろ試して、自分好みに構築するのがいいですね。

ALEXAさんで遊ぼう。手持ちの音楽をECHOで流す方法、その2

前回の投稿で、手持ちの音楽は基本的にAmazon Echoで再生できない、と書きました。

しかし、次のような方法を使用すれば、 Amazon Echoでも再生できます。

その方法とは、

Amazon Musicストアで音楽を購入する。

そうすれば、Amazon EchoをBluetoothスピーカー化しなくてもAmazon Echoで再生できます。

ただし、AlexaはAmazon Musicストアの曲を認識することはできないようです。

Alexaさんは、あくまでも連携した音楽ストリーミングサービスの楽曲しか認識できないようです。

再生するには、スマートフォンなどのAlexaアプリ経由でリストから楽曲を選択し、再生指示を出すしかありません。

この程度だったら、Amazon Musicストアを利用しなくてもいいかも。

なぜなら、

オイラのデスクトップ環境はハイレゾ再生できる環境にあるからです。

ハイレゾ対応ポータブルアンプ&ハイレゾ対応ヘッドホンがあるのです。

だとすれば、moraで購入して聞いた方が良いのかな、って思いました。

Alexaさんで遊ぼう。手持ちの音楽をEchoで流す方法

Amazon Echoでは、基本的に他音楽ストリーミングサービスと連携して音楽を再生するしかありません。

それでも、無理矢理手持ちの音楽も流してしまおう、という話。

早い話が、Amazon EchoをBluetoothスピーカーにしてしまうのです。

Alexaアプリからデバイス一覧のEcho・Alexaをタップ。

この画面でPC・スマホなどのデバイスとペアリングを行います。

Echo側でペアリングした後、PC・スマホの側でもEchoデバイスをペアリングします。

これでBluetoothで繋がります。PC・スマホの音がそのままEchoで再生されます。

ただ、この方法は完全にAlexaさんを殺していることになります。

Alexaさんをうまく生かすには、やはりAmazon Music Unlimitedを使用するしか無いでしょう。

さあ、みんな叫ぶんだ。

「アレクサ、 Amazon Music Unlimited に登録して」

VPSのFTPポートを変更する

これはえらい人からの指示で調べた。

まずは、vsftpsにポート設定を書き足す。

$ sudo vi /etc/vsftpd.conf

listen_port=制御用ポート番号
pasv_enable=YES
pasv_min_port=データ通信用ポート番号(下限)
pasv_max_port=データ通信用ポート番号(上限)

まぁ、この設定を書き込むには、FTPの仕組みを理解しなければいけないわけで。

FTPは制御用ポートとデータ用ポートの2つを使用します。

デフォルトでは制御用ポートが20、データ用ポートが21です。

なので、iptablesの設定も、両方のポートを開ける必要がありました。

FTPのポート番号を変える場合はパッシブモードにする必要があります。

パッシブモードにした場合、データ用ポートはサーバ側でランダムに決定されます。

でも、本当にランダムだと、ファイアーウォールの設定が面倒なので、

そのポート番号の範囲を決めてあげる必要があります。

その下限をpasv_min_portで、上限をpasv_max_portで設定します。

つまり、ここでポートを指定してあげれば、ファイアーウォールはその部分だけ開ければ良いことになります。

まぁ、今回はめんどうなので、上限も下限も同じ値にして、データ用ポート番号も固定にしました。

FTPサーバを再起動

$ sudo /etc/init.d/vsftpd restart

iptableのポートを開けます

$ sudo iptables -I INPUT  -p tcp –dport 制御用ポート番号 -j ACCEPT

$ sudo iptables -I INPUT  -p tcp –dport データ用ポート番号(下限):データ用ポート番号(上限) -j ACCEPT

この時点で、新しいポート番号でデータ転送ができることを確認。

変更前のポート番号を閉じる

まずは、iptableの設定一覧を表示

$ sudo iptables -nL –line-number

一覧の中から削除する設定番号を指定する。

$ sudo iptables -D INPUT 設定番号

iptableの設定を保存

$ sudo iptables-save

これで完了です!

iptableの設定を保存する

VPSでiptableの設定しましたが、

これだけでは再起動すると設定が消えてしまいます。

これを解決します。

# apt-get install iptables-persistent

これをインストールすると設定が保存できます。

保存には、

# iptables-save

と撃ち込めばOK。

これをやっておけば、再起動してもiptableの設定が復元します。

VPSにファイアーウォールを設定する

今回はVPSにファイアーウォールを設定します。

使用するのはiptablesです。

これを設定しないと、全ポートが解放されている状態となり、

仮に、サーバに悪意のあるソフトが仕込まれ、ポートをlistenしている状態になっていると、

攻撃者はそのポートにアクセスするだけで簡単にサーバを書き換えることができてしまいます。

しかし、iptableを設定することで、外からの許可されたポート以外は全てiptablesでブロックしてくれます。

まずは、現状を確認

# iptables -nL

たぶん全ポート開放状態です。

データを持たないパケットを破棄

# iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

SYNflood攻撃と思われる接続を破棄

# iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

ステルススキャンと思われる接続を破棄

# iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

localhostからの通信とpingを許可

# iptables -A INPUT -i lo -j ACCEPT

httpによるアクセスを許可

# iptables -A INPUT -p tcp -m tcp –dport 80 -j ACCEPT
# iptables -A INPUT -p tcp -m tcp –dport 443 -j ACCEPT

その他、使用しているサービスのポートを許可する

# iptables -A INPUT -p tcp -m tcp –dport [ポート番号] -j ACCEPT

確立済みの通信を許可に設定

# iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

許可した通信以外のサーバに受信するパケットを拒否し、サーバから送信するパケットを許可

# iptables -P INPUT DROP
# iptables -P OUTPUT ACCEPT

この状態で、使用しているサーバアクセスが一通りできることを確認する。

できなければ、そのポートを開放する。

で、この設定を保存するんだけど、通常ならservice iptables saveでできるはずなんだけど、

なぜかできないので、スクリプトを作って、再起動する度に設定を行うようにする。(めんどくせー)

これでファイアーウォールの設定できました!