今だけ人気マンガ100円レンタル特集♪

Win32APIやLinuxでAPIプログラミングを組んでいった場合、こういうAPIがほしいと感じることがあります。APIを実際作ることは可能なのでしょうか?また、どのような手順となりますでしょうか?よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

がると申します。


んっと。APIってのは「Application Programming Interface」のことでいいんですよね?
普通に関数作ったりクラス作ったりして、必要に応じてそれをスタティックライブラリ化したりシェアードライブラリ化したりすれば、それがAPIになります。
手順的には、Linuxの場合は
・欲しい関数とかクラスとかを作る
・gccで-cオプションつけてコンパイルして、.oファイルを作成する
・スタティックライブラリ作るならar、シェアードならldコマンドでライブラリを作成する
こんな感じで可能です。
Windowsの世界観ですと、dllという名前がそれに相当するかと思うのですが。ちとそのあたりは不得手なので曖昧ですみません。
    • good
    • 0

>APIを実際作ることは可能なのでしょうか?


不可能です。
OSの修正ができる(WindowsやLinuxのコーディングを直接やってる)人ならできると思います。

APIを「ライブラリ」の意味で使っている(少し違っていますが...)なら、可能ですし、普通です。
    • good
    • 0

再配布可能なDLLやSOなどのライブラリファイルを作れば如何ですか

    • good
    • 0

普通に関数を作るだけではダメなのですか?

    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Qプログラミング言語のAPI

プログラミング言語の『API』にあたるものって具体的には何なのでしょうか?

例えば,C言語の場合『API』にあたるのはprintfやscanfなどの『標準関数全体』という解釈で合っているのでしょうか?


また,ライブラリとAPIの関係についても教えていただけると嬉しいです.

読んだ本の中で少し触れられていたのですが,表現が曖昧であまりよく分かりませんでした・・・.

Aベストアンサー

API というのは、もともと OS が用意しているシステムコールのことを差しています(「API システムコール」で検索すると、そういう説明をしているページが山のように見つかります。)。さきほど、20年ぐらい前の古い書籍まで含めてざっと書棚に目を通しましたが、一般の人に API という言葉が聞こえるようになったのは OS/2 のころです。それまでは MS-DOS も Unix も「システムコール」と呼ぶのが普通でした。(なぜ MS-DOS でシステムコールと呼んでいたのを OS/2 で API という名称に変えたのか、とかは省略します。類似の言葉にスーパーバイザーコール、というのもありますが、これも省略)

その後、コンピュータシステムは複雑になり、OS とアプリケーションプログラム、で完結する、という時代ではなくなってきます。いわゆる「ミドルウェア」が出現してくるわけですが、クライアント-サーバモデルで説明されることが多い「サーバ」側のプログラムを作成するためには、「サーバを呼び出す」必要が出てきたのです。(たとえば、データベースサーバ上にデータベースを構築するには、データベースサーバに「仕事を依頼」しなくてはいけません) これは、OS がもともと持っている「API」と似ている(プログラマからは区別ができない)ので、同じ「API」という言葉で呼ぶようになりました。つまり、「OS 以外のシステムが用意している機能をアプリケーションから呼び出す」という意味でも API という言葉が使われるようになったのです。(OS が持っている機能を使いたいから「OS に依頼する」のが API ですが、データベースサーバの機能を使いたいから「データベースサーバに依頼する」のも API でいいじゃないか、ってことです。データベースプログラムは OS から見ればひとつの「アプリケーション」に過ぎませんが、プログラマから見ればシステムの一部として「あらかじめ機能が提供されているかのように」見えます)

それから十年以上が過ぎて、Web や Java など、新しい機能が搭載されたオペレーティング環境が発明されました。Web や Java を作った人たちは、ネット上の Web サーバや Java の処理系を呼び出す仕組みを作ったのですが、この仕組みにも名前をつけないと人と話すときに不便です。(「今度作った Java の処理系の機能を呼び出す仕組みの xxx という部分なんだけどさ」「あー、うんうん、その Java の処理系の機能を呼び出す仕組みの xxx ってこないだ話してたやつだよね」「そーそー、その Java の処理系の機能を呼び出す仕組みの xxx を改良したんだけどね・・・」って、これでは落語のネタにはなっても、会話になりませんよね。やはり呼び名は必要です) そこで、ふと思いつきました。「自分のプログラムから他の機能を呼び出すことを API と呼んでいるんだから、これにも API と名前をつけてしまえ」 かくして、これらも「API」という名称で呼ばれることになったわけです。が、さすがにもともとの「API」とはあまりにかけ離れているので、「遠慮して」Web API とか Java API と、「形容詞」をつけたわけです。「端っこでいいから、仲間に入れてね」ってわけです。

「C 言語の API」というのは、正しいのか?
これはやはり一般的であるとは言い難いです。現在では API という意味がもともとの意味から拡張されて使われていますが、それでもなお「システム側がプログラムをする人たちのために用意している呼び出し方法」であることに変わりはありません。ですから、「C 言語の」というのが、「C 言語の一部であるところの」とか「C 言語に包含される」という意味であるのなら、「C 言語の API」という言葉は、やはりありません。API は「C 言語の外」であるシステム(OS とかサーバ)が用意しているものであり、C 言語はそれを「呼び出す」ことができるに過ぎません。もしかすると、呼び出されたシステムも「C 言語で書かれている」のかもしれませんが、それは結果論であり、システムを記述した言語が C であれ、Pascal であれ、マシン語を直接書いたのであれ、決められた呼出し手順(これを「API の仕様」と言います)にしたがって呼び出せば、C 言語からであろうと他の言語からであろうと、この API を利用することができます。つまり、呼び出す側からは呼び出されたシステムがどのように作成されたかはブラックボックスであり、内部的にどのように処理されているのかを気にせずに呼び出せるのが API です。呼び出されたシステムは所望の動作を行なったのち、呼び出したプログラムに戻ってきます。

・ プログラミング言語の『API』とは?

一般的に、この言葉は使われません。API はシステム側がプログラムのために用意している「呼び出し窓口」のことを指します。ですから、通常は「Unix の API」とか「Windows の API」というように、OS をはじめとするシステム側の名称に続いて使われる言葉です。最近ではサーバなど「広義のシステム」に属するものが増えているため、「データベースの API」という言い方もされていますが、本来の意味でのシステムは OS を指していたと理解するところから始めるとよいでしょう。

・ 例えば,C言語の場合『API』にあたるのはprintfやscanfなどの『標準関数全体』という解釈で合っているのでしょうか?

あっていません。printf などは「標準入出力関数」とか「標準入出力ライブラリ」と呼ばれることがありますが、これらは言語処理系を作成した人がプログラマのために用意するものです。一般的にこのような「有用なルーチンのかたまり」をライブラリと呼びますが、API とは呼びません。(ライブラリの効用は他にもありますが、話がそれてしまうので割愛します)

・ また,ライブラリとAPIの関係についても教えていただけると嬉しいです.

入出力などは、OS 側が用意しているものです。言語処理系で入出力が必要な場合、入出力ライブラリや入出力文を呼び出します。そのライブラリや入出力文ルーチンの中で API を呼び出して OS に入出力を依頼し、最終的にプログラマは入出力結果を見ることができます。ただし、「ライブラリ」の中には「算術ライブラリ」など入出力を伴わないものもあります。このようなライブラリを呼び出しても API は呼び出されないので、「ライブラリの内部では必ず API を呼び出している」とは言えません。

> 読んだ本の中で少し触れられていたのですが

以上の説明で、本の記載事項とうまくかみあうと思いますが、いかがですか?

API というのは、もともと OS が用意しているシステムコールのことを差しています(「API システムコール」で検索すると、そういう説明をしているページが山のように見つかります。)。さきほど、20年ぐらい前の古い書籍まで含めてざっと書棚に目を通しましたが、一般の人に API という言葉が聞こえるようになったのは OS/2 のころです。それまでは MS-DOS も Unix も「システムコール」と呼ぶのが普通でした。(なぜ MS-DOS でシステムコールと呼んでいたのを OS/2 で API という名称に変えたのか、とかは省略し...続きを読む

Q戻り値で構造体を返すことは可能でしょうか?

perlでは以下のように2つの戻り値が可能ですが、C言語では
それができるのでしょうか?
my (ret1, ret2) = test1();

よくやるのは、引数にポインタを渡して、内容を書き換える手を使っていますが、戻り値を複数返せたら、直感的にわかりやすいかなと思いまして・・・

Aベストアンサー

C言語から遠く離れた者ですが、

>>> よくやるのは、引数にポインタを渡して、内容を書き換える手を使っています

これが常識でしょう。これが直感的に理解できるようにC言語を身に付ける必要があるのではないでしょうか。

Q2次元配列を戻り値とする関数?

いつもお世話になっています。

角度を入力すると、
2×2の2次元配列を戻す
関数を作りたいのですが、
コンパイルすると、
戻り値の型のところで、
不正な変換だというエラーが出て
うまく行きません。

参考書を何度も読み直して
戻り値の型をポインタのポインタにするなど、
いろいろトライしてみたのですが、うまく行きません。

typedef を使う方法も考えましたが、
他にもっとすっきりする方法はないでしょうか?

どなたか参考URLをお教えくださるか、
解決策を教えてください。
よろしくお願いします。

ちなみに、この関数は大凡下記の通りです。

double** Matrix(double sita)
{
double mat[2][2];
mat[0][0]= cos(sita);
mat[0][1]= sin(sita);
mat[1][0]=-sin(sita);
mat[1][1]= cos(sita);

return mat;
}

Aベストアンサー

補足です。
もし、配列にこだわらないのであれば構造体を宣言してその値を返すようにした方が良いかもしれませんね。
struct mat_str {
 :(配列でも、それぞれ意味のある変数でもOK)
};

struct mat_str Matrix (double sita)
{
 struct mat_str mat;
 :
 return mat;
}

呼び出し側は、
struct mat_str result;
result = Matrix(1.0);
で、Matrix内のauto変数の値が 呼び出し側の resultに代入されます。

typedef struct mat_str stMat;
とすれば見やすくなりますね。

Qコンパイルエラー invalid operands to binary

自己啓発で入力文字列をBASE64デコードする関数を作っているのですが、L20~L23(a[0] = strchr(b64, p[0]) - b64;)でコンパイルエラーinvalid operands to binaryが発生して色々試行錯誤しているのですが、どうしてもエラーがとれません。
ソースをここに書くのは大変恐縮なのですが、原因がわかる方がいらっしゃいましたら、教えていただけないでしょうか?

char *Base64n(unsigned char *buf, size_t length, size_t *outlen)
{
const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst         uvwxyz0123456789+/=";
unsigned char *p;
unsigned char *q;
unsigned char a[4];
char *RtnBuf;
int j=0;
int cnt;

RtnBuf = (char *)malloc(length+1);
memset(RtnBuf, 0, length+1);

p = (unsigned char*)buf;
q = (unsigned char*)RtnBuf;
cnt = 0;
while(*p != 0) {
a[0] = a[1] = a[2] = a[3] = 0;
a[0] = strchr(b64, p[0]) - b64;
a[1] = strchr(b64, p[1]) - b64;
a[2] = strchr(b64, p[2]) - b64;
a[3] = strchr(b64, p[3]) - b64;

q[0] = ((a[0] << 2) | (a[1] >> 4)) & 0xff;
cnt++;

if (p[2] != '=') {
q[1] = ((a[1] << 4) | (a[2] >> 2)) &0xff;
cnt++;
}
if (p[3] != '=') {
q[2] = ((a[2] << 6) | a[3]) & 0xff;
cnt++;
}
p += 4;
q += 3;
}
*outlen = cnt;
return(RtnBuf);
}

コンパイルはRed Hatでgccを使ってコンパイルしています。
引数は第1引数がデコード対象の文字列、第2引数がデコード対象文字列長、第3引数がデコード後の文字列長で、戻り値がデコード後の文字列です。

自己啓発で入力文字列をBASE64デコードする関数を作っているのですが、L20~L23(a[0] = strchr(b64, p[0]) - b64;)でコンパイルエラーinvalid operands to binaryが発生して色々試行錯誤しているのですが、どうしてもエラーがとれません。
ソースをここに書くのは大変恐縮なのですが、原因がわかる方がいらっしゃいましたら、教えていただけないでしょうか?

char *Base64n(unsigned char *buf, size_t length, size_t *outlen)
{
const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst ...続きを読む

Aベストアンサー

手元にgccが無いので、Windowsのbcc32でコンパイルしてみたところ、
エラーが出ずに通ってしまいました。
だから自信がないのですが…。

a[0] = strchr(b64, p[0]) - b64;



a[0] = strchr(b64, p[0]) - b64[0];

に変えてみたらどうでしょう。
"invalid operands to binary"
は、たぶん、マイナスの両側で型が違っていることを
表しているのではないでしょうか。(←これも自信なし)
strchr()が返すのはchar *型ですが、
b64の型は、charの配列型です。
型が違うので、コンパイラが不正と判断したのかもしれません。

とするとbcc32でなぜ通ったかが問題になるのですが…。
C言語規格でも、ポインタ同士の引き算のところは
ややこしくなっています。
規格解釈の違いがあるのかもしれません。

Qセマフォとmutexの違いは?

排他制御としてセマフォとmutexがありますが、
この二つの違いがよくわかりません。
自分で調べてみたところ、
・セマフォ…プロセス間排他制御。複数ロックがかけられる。
・mutex…スレッド間排他制御。ロックは一つだけ。

と言うような違いがあるようなのですが、これだけの差なんでしょうか?
(これだけの差、と言ってる時点で筋違いだったら申し訳ありません)
また、セマフォをスレッド間排他制御に用いたり、
mutexをプロセス間排他制御に用いることは可能なのでしょうか?
可能だとしたら、これらが2種類存在する理由も教えていただきたいです。

Aベストアンサー

> >一般論としては、Mutexは「カウントを1に限定した」特殊化したSemaphoreです。
> とのことですが、これはWin32以外の環境だと
> これ以上の違いはないと言うことでしょうか?

「一般論」と書いた意味を取り落とされているのではないかと思います。

「一般論としては〇〇」なのですから、「Win32以外の環境」も含めて「各論」では「必ずしも〇〇とは限らない」とご理解ください。

なお、ご指摘のとおり、あるリソースを排他的に利用するだけであればMutexを使用するかわりにカウントが1のSemaphoreを使用することができます。(特定の環境での、MutexとSemaphoreの環境依存の動作を除けば、ですが。)

ではなぜ2種類が用意されている(用意されている環境が存在する)のかといえば、リソースの排他的利用は非常によくあることなので、これに特化した機能を用意すればより良いであろう、というシステムデザイナの判断によるものと考えられます。

ここで言う「より良い」は、あるデザイナにとっては「便利性」、また別のデザイナにとっては「消費リソースが少ない」と、これまた考え方はいろいろでしょう。

> >一般論としては、Mutexは「カウントを1に限定した」特殊化したSemaphoreです。
> とのことですが、これはWin32以外の環境だと
> これ以上の違いはないと言うことでしょうか?

「一般論」と書いた意味を取り落とされているのではないかと思います。

「一般論としては〇〇」なのですから、「Win32以外の環境」も含めて「各論」では「必ずしも〇〇とは限らない」とご理解ください。

なお、ご指摘のとおり、あるリソースを排他的に利用するだけであればMutexを使用するかわりにカウントが1のSemaphore...続きを読む

QライブラリとAPIについて

はじめまして。
すごく初歩的な質問ですが
誰かライブラリとAPIの違いを教えてください。
どちらもプログラムでよく使うものをまとめたものみたいですが両者の違いが分かりません。
またDLLはライブラリの一部なんでしょうか?

Aベストアンサー

> ここでまた疑問なんですがライブラリ(複数の関数)も
> API(1つの関数)も同じ関数ならAPIを入れなくても
> 直接アプリケーションとライブラリでできないんでしょうか。

ん?
APIは一つの関数とは限らないです。複数の関数を総称してAPIってこともあります。

ただの関数でも、アプリとのインターフェイスになるものはAPI(の一部)ですし、
インターフェイスの役をしない関数もあります。

関数そのものをAPIと呼ぶことも多いですが、必ずしも一致しません。
APIを実装(実現)する代表格が関数であって、関数=APIでもAPI=関数でもないです。

> 直接アプリケーションとライブラリでできないんでしょうか。

何ができないのかよく分かりませんが、APIってのは本質的には「取り決め」なので、
これがちゃんとしてないと、別の担当者になったときに困ったりします。

郵便局員の担当が「いつもの人」で互いに意思疎通できてれば多少のことはケアしてくれますけど、
別の担当になったとたんに話が通じなくなったり。(Interfaceが定まってない)
これが、応対マニュアルとか、申込用紙とか完備してきちんと取り決めがされていると、
別の担当者でも同じ手順で応対してもらえます。(Interfaceが定まっている)

APIってのは、「アプリケーションがこういうお願いをしたら、私はこういう応答をします」っていうお約束と、
それを実際にやってくれる担当者のことであって、関数は行員、ライブラリは郵便局。

APIがある利点というのは、利用者(アプリ)が郵便局内のごたごたとか業務フローを気にせずに、
窓口で決まった手順でお願いするだけで、誰が担当でもきちんと書留を送って貰える。
こういう、決まった手順をコミットして、何かをお願いすれば望む結果が返ってくると期待できるというところにあります。
これがばらばらだと、利用者が郵便局の支店ごとに別の手順を覚えるとか、窓口の担当者ごとに手順を確認するなどが必要になったりするのです。

> ここでまた疑問なんですがライブラリ(複数の関数)も
> API(1つの関数)も同じ関数ならAPIを入れなくても
> 直接アプリケーションとライブラリでできないんでしょうか。

ん?
APIは一つの関数とは限らないです。複数の関数を総称してAPIってこともあります。

ただの関数でも、アプリとのインターフェイスになるものはAPI(の一部)ですし、
インターフェイスの役をしない関数もあります。

関数そのものをAPIと呼ぶことも多いですが、必ずしも一致しません。
APIを実装(実現)する代表格が関数であ...続きを読む

Qスレッドの安全な終了のさせ方

スレッドの安全な終了のさせ方

 メインスレッドにてCreateThread命令を使い、あるサブスレッドを作りました。
このサブスレッドは内部でmallocを使い動的に配列領域を確保して
その配列領域をforループ等で「かなり時間の掛かる処理」として繰り返し
アクセスしています。
ループが終了した時に「free」を実行してmalloc領域を開放しています。

アプリ終了時にメインスレッドからこのサブスレッドを終了させるのに
メインウインドウにWM_DESTROYメッセージが送られた時、これまで単に
そこで「CloseHandle(hSubThread);」とだけ書いていたのですが、
もしかしたらこれでは場合によっては(サブスレッドがループ処理中だったら)
malloc領域が開放されずにリークしてしまうのではないかと思いました。

 そこでイベントオブジェクトを使い、サブスレッドがループ処理中の
時には非シグナル状態にして、ループが終了しfreeで領域を開放した後
シグナル状態にするということにして、メインスレッドはそれを
WaitForSingleObjectで待つという構造にしました。

ところが「メインスレッドに待ちを作るな」という言葉通り、これでは
上手く行きませんでした。サブスレッドはその時間の掛かる処理の
最中でSendMassage等でメインスレッドの処理を促すような命令を
(例えばその処理の進捗状況を表示するなど)を幾つも行っていたので、
もしWaitFor~でメインを待たせると「サブスレッドの処理も進まなくなり
結果両方がロックして動かなくなってしまう」という悲しい状況に
嵌ってしまうのです。

SendMessageを徹底的に無くすということも考えたのですが、
(例えばPostMessageに書き換えるなどもやってみたのですが、これは
全く意図した動作をしてくれない場合もあり)、別の方法では
どうしても代替できないケースもあって、全て消すというのは
現実的ではないのかもと。。

 このようなサブスレッドを安全に終了させるにはどうしたら良いでしょうか?
あるいは単にデストロイ時にCloseHandleとするだけでも良いのでしょうか?

スレッドの安全な終了のさせ方

 メインスレッドにてCreateThread命令を使い、あるサブスレッドを作りました。
このサブスレッドは内部でmallocを使い動的に配列領域を確保して
その配列領域をforループ等で「かなり時間の掛かる処理」として繰り返し
アクセスしています。
ループが終了した時に「free」を実行してmalloc領域を開放しています。

アプリ終了時にメインスレッドからこのサブスレッドを終了させるのに
メインウインドウにWM_DESTROYメッセージが送られた時、これまで単に
そこで「CloseHandle(hSu...続きを読む

Aベストアンサー

>SetEvent(hEventObject1);//イベントオブジェクトをシグナルに
スレッド終了を判断する場合はスレッドのハンドル自身を見た方が確実です。
HANDLE thread_handle = ::CreateThread(略);
(略)
::WaitForSingleObject( thread_handle , INFINITE );
スレッドは終了時にハンドルがシグナル状態になります。


>SendMessage(hMainWnd,....);
>//メインウインドウに何かのメッセージを送信
>//なってた時に処理が進まなくなる。
名前から察するにhMainWndはメインスレッドで動いているようですが
そのメインスレッドの処理がWaitForSingleObjectによって止まっているのなら処理は返ってきません。
つまりサブスレッドがメインスレッドとなんらかのやりとりをしたいなら、
この時点でメイン側はWaitForSingleObjectで待ってはいけません。

1. Main -> Subに終了前準備しろと通知
2. Sub -> Mainに終了前準備完了を通知
3. Main -> Subに終了しろと通知
4. MainはSubが終了するのをWaitForSingleObjectで待つ。

>SetEvent(hEventObject1);//イベントオブジェクトをシグナルに
スレッド終了を判断する場合はスレッドのハンドル自身を見た方が確実です。
HANDLE thread_handle = ::CreateThread(略);
(略)
::WaitForSingleObject( thread_handle , INFINITE );
スレッドは終了時にハンドルがシグナル状態になります。


>SendMessage(hMainWnd,....);
>//メインウインドウに何かのメッセージを送信
>//なってた時に処理が進まなくなる。
名前から察するにhMainWndはメインスレッドで動いているようですが
そのメインスレッドの...続きを読む

QVC++でSQL Serverに接続するにはどのようにしたらよいでしょ

VC++でSQL Serverに接続するにはどのようにしたらよいでしょうか?
DBもVisual Studioも初心者なのでまったくわかりません。

開発環境は
Microsoft Visual C++ 2008 standard Edition
OS XP SP3
Microsoft SQL Server

プロジェクトの種類はWin32コンソールアプリケーションかMFCアプリケーションのダイアログベースです。
接続できるならどちらでもよいです。
接続の他にもDBに入れらているデータを取得する方法もわからないです。
本当に初心者なので丁寧に教えていただけると大変助かります。
よろしくお願いいたします。

Aベストアンサー

こんにちは。
以下を参考にしてください。

http://support.microsoft.com/kb/818779/ja

私は面倒なC++はいやなので、もっぱらC#で開発しています。
しかし、Microsoftの言によればC++でも同様の開発ができるはずなので、
試しにやってみましたが、私の場合は下記コードでConsoleアプリケーションとしては
うまくいきました。
確かにできるのですが、同じコードを書くならC#の方がずっと楽です。
何が楽かと言うと、インテリセンスがめちゃくちゃ強力だからです。

私の場合、SQLServerのDBである「放送大学記録」にはいくつかのテーブルがあり、
テーブル「dbo.テレビ講義一覧」は
 DVD bit型
 講義名 nvarchar(255)
 よみがな nvarchar(255)
の3つの列で構成されています。


// C++ConsoleSOLTest.cpp : メイン プロジェクト ファイルです。

// This is the main project file for the VC++ application project
// that is generated by using the Application wizard.

#include "stdafx.h"

#using <mscorlib.dll>
#include <tchar.h>
#using <System.Dll>
#using <System.Data.Dll>
#using <System.Xml.Dll>

using namespace System;
using namespace System::Data;
using namespace System::Xml;
using namespace System::Collections;
using namespace System::Data::SqlClient;

int _tmain(void)
{
SqlConnection* objConn;
try
{
objConn = new SqlConnection("Data Source=ICHHABEHUNGER\\SQLEXPRESS;Initial Catalog=放送大学記録;Integrated Security=True");
objConn->Open();

SqlDataAdapter* dAdp = new SqlDataAdapter("Select * From テレビ講義一覧", objConn);
DataSet* dSet = new DataSet("講義");

dAdp->FillSchema(dSet,SchemaType::Source, "講義");
dAdp->Fill(dSet,"講義");

DataTable* dTbl = dSet->Tables->Item["講義"];

IEnumerator* iEnum = dTbl->Rows->GetEnumerator();

while(iEnum->MoveNext())
{
Console::WriteLine("{0} {1}",dynamic_cast<String*>(dynamic_cast<DataRow *>(iEnum->Current)->get_Item("講義名")),
dynamic_cast<String*>(dynamic_cast<DataRow *>(iEnum->Current)->get_Item("よみがな")));

}
}
catch(Exception *ex)
{
Console::WriteLine( ex->Message );
}
__finally
{
objConn->Close();
}
return 0;
}

参考URL:http://support.microsoft.com/kb/818779/ja

こんにちは。
以下を参考にしてください。

http://support.microsoft.com/kb/818779/ja

私は面倒なC++はいやなので、もっぱらC#で開発しています。
しかし、Microsoftの言によればC++でも同様の開発ができるはずなので、
試しにやってみましたが、私の場合は下記コードでConsoleアプリケーションとしては
うまくいきました。
確かにできるのですが、同じコードを書くならC#の方がずっと楽です。
何が楽かと言うと、インテリセンスがめちゃくちゃ強力だからです。

私の場合、SQLServerのDBである「放送大学記録...続きを読む

Q起動しているサービスを確認するコマンド

初歩的な質問で恐縮ですが、ご教示いただけますと幸いです。

起動しているサービスを確認するために以下の2つのコマンドを打ってみるのですが、結果(出て来るサービス名)が違います。
このコマンドの違いについてご教示いただけますでしょうか。

(1)service --status-all
(2)chkconfig --list

Aベストアンサー

(1)service --status-all

サービスの現在のステータスを調べるコマンド

(2)chkconfig --list

OSのブート時に自動起動するサービスを調べるコマンド

違いが出るのは、
・ブート後に手動あるいは他のコマンドから起動したサービス
・ブート後に手動あるいは他のコマンドから、あるいはエラーで停止したサービス
・ブート後に実行はされるがすぐに停止して常駐しないサービス (ntpdate とか)

あるいは、(1)ではサービス名が表示されない物もあるので、どのサービスがどんなステータス出力をするのか知っておく必要もありますね。(service network statusとか)


人気Q&Aランキング