構造体ポインタを使おう

C言語ここまで出来れば大丈夫!という基準は何か?

・とりあえず10,000行
・malloc/free使えりゃOK
・標準ライブラリ以外も使えるようになった
・10行でテトリスを書いた、私はナニカサレタヨウダ

うーん、人によってさまざまでしょう。

私なりの考えとしては、
「構造体ポインタ」を使えるでしょうか。

つまり、OpenCVでよく見る

// オブジェクトの確保
IplImage *img = cvCreateImage(...);

// 操作
cvThreshold(img, ...);

// 解放
cvReleaseImage(&img);
のような仕組みを理解できたらOK!ってことです。
ちなみに私はcvReleaseImage()の引数がなぜポインタのポインタなのかが未だに理解できません。無駄じゃね?

グローバルな構造体で済む場合もありますが、複数のファイルから構成されるプログラムの場合、extern宣言ばかりになってどこで定義したかわからなくなります。関数に渡すにしても参照渡しの方が効率が良いですし、何より.より->の方がカッコ良いです。

#include <stdio.h>
#include <stdlib.h>

/* 画像データ */
struct IMAGE {
int width;
int height;
unsigned char *data;
};
typedef struct IMAGE *ImageID;

/* 画像オブジェクトの生成 */
ImageID createImage(int img_width, int img_height);

/* 画像の2値化 */
void binalizeImage(ImageID img, int lower, int upper);

/* 画像の解放 */
void releaseImage(ImageID img);
10行目でImageIDにtypedefしているのがミソです。
ポインタを「オブジェクトのID」と考える方法はOpen Dynamics Engineを参考にしています。

#include "image.h"

/* 画像オブジェクトの生成 */
ImageID createImage(int width, int height)
{
ImageID img = (ImageID)malloc(sizeof(struct IMAGE));
if (!img) return 0;

/* 内部データ */
img->width = width;
img->height = height;
img->data = (unsigned char*)malloc(img->width * img->height * sizeof(unsigned char));
if (!img->data) {
free(img);
return 0;
}
return img;
}

/* 画像の2値化 */
void binalizeImage(ImageID img, int lower, int upper)
{
if (!img) return;

/* 閾値以内なら255 */
for (int i = 0; i < img->width*img->height; i++) {
if (lower < img->data[i] && img->data[i] < upper) img->data[i] = 255;
}
}

/* 画像の解放 */
void releaseImage(ImageID img)
{
if (img) {
free(img->data);
free(img);
img = 0;
}
}
上の例のように、実体はmallocで確保して、ユーザにはポインタだけ渡してやります。ポインタで管理する利点は「オブジェクトの確保に失敗したらヌルポインタを返す」とすれば、そのオブジェクトが存在しているか否かがわかることです。

#include "image.h"

int main(int argc, char **argv)
{
/* 画像の生成 */
ImageID img = createImage(320, 240);

/* 2値化 */
binalizeImage(img, 127, 255);

/* 解放 */
releaseImage(img);
return 0;
}
いやぁ、プログラミングって奥が深いですね!

構造体ポインタはリスト構造を組むときにも使えるので便利なテクニックです。

まぁ、一番いいのは他の人にも読みやすいコードが書けることですけどね!
スポンサーサイト



AquesTalk使ってみた

CV Droneに喋ってもらおうと考えて「AquesTalk」に手を出してみました。

ここからダウンロードして、
http://www.a-quest.com/products/aquestalk.html

ヘッダをインクルード、
#include <AquesTalkDa.h>

関数は同期タイプだと、
AquesTalkDa_PlaySync("ほげほげ");

非同期は、
hMe = AquesTalkDa_Create()
AquesTalkDa_Play(hMe, "ふがふが")
AquesTalkDa_Stop(hMe);

これだけで声出せるのってすごいですね。
ライブラリのサイズもとても小さいですし。

今回作ったサンプルです→aquest_test.zip

pthreadを使ってみよう

マルチスレッド大好きな私ですが、pthread(POSIX Threads)は扱ったことがありませんでした。

にわかでスンマセン。

「Linuxに移植したい」との声を受けて、最新のCV Droneには従来の_beginthreadex()による実装からpthreadを用いたものに変更しています。といってもFTPの部分がまだWinINet依存ですが。

スレッドの生成はこんな感じです。

#include <pthread.h>

// 生成
pthread_t thread;
pthread_create(&thread, NULL, loop, NULL);
こちらはスレッド関数です。

// スレッドの処理
void* loop(void *arg)
{
while (1) {
// 何かの処理
// :
pthread_testcancel(); // 外部から終了させるときに必要
}
return NULL;
}
それにしてもなんで関数ポインタのポインタを渡すんでしょう?

外部からスレッドを終了させる仕組みがあるのがいいですね。

// 外部から終了
pthread_cancel(thread);
pthread_join(thread, NULL);
Win32APIでもTerminateThread()で同じことができますが、危険なのであまり使いたくありません。
volatileのフラグを排他制御しながらアレコレするのも面倒ですしね。

FFmpegをLGPLでビルドする

そういえばLGPLでビルドする方法を紹介すると昔の記事に書いていましたね。

すっかり忘れてました。


1. MinGWのインストール
 http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/
 からダウンロードしましょう。
download_mingw.jpg

 ダウンロードできたらインストールしましょう。
 mingw_install.jpg
C++ Compiler,MSYS Basic System,MinGW Developer Toolkitにチェックを入れるのを忘れずに。

2. NASMのインストール
 http://www.nasm.us/pub/nasm/releasebuilds/2.10.07/ からダウンロードしましょう。
download_nasm.jpg

Visual Studioのコマンドプロンプトを開いて
> C:\MinGW\msys\1.0\msys.bat
MinGWが開いたら
$ cd nasm-2.10.07
$ ./configure –prefix=/mingw
$ make
$ make install

3. FFmpegのインストール
 http://www.ffmpeg.org/download.html からダウンロードしましょう。
download_ffmpeg.jpg

Visual Studioのコマンドプロンプトを開いて
> C:\MinGW\msys\1.0\msys.bat
MinGWが開いたら
$ cd ffmpeg-1.2
$ ./configure --enable-shared --disable-gpl
$ make
$ make install
これで完了です。

ビルドしたファイルは「C:\MinGW\msys\1.0\local」に入っています。

ポインタとインクリメント

突然ですが、

*i++;

ってどう解釈されると思いますか?

(*i)++;

と同じ!と考えた人(私を含む)は間違いです。その場合のコードは*i+=1となります。

正しくは、

*(i++);

です。i[1]にアクセスすると考えたほうが良いでしょうか?

紛らわしいコードは書かないほうがいいな、と考えた一日でした。
プロフィール

puku

Author:puku
暇な時はゲームかプログラミングしてる人だよ。
だいたい月1更新。
CV Drone はこちら(GitHub)

最近はQiitaでOnsenUI2で遊んでいる。

最新記事
最新コメント
最新トラックバック
検索フォーム
カレンダー
03 | 2021/04 | 05
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -
月別アーカイブ
カテゴリ
スポンサードリンク
RSSリンクの表示
FC2カウンター
リンク
ブロとも申請フォーム

この人とブロともになる

アクセスランキング
[ジャンルランキング]
コンピュータ
607位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
120位
アクセスランキングを見る>>
FC2ブログランキング

FC2Blog Ranking

QRコード
QR