外出自粛中でも楽しく過ごす!QAまとめ>>

C・C++初心者です。宜しくお願い致します。
サーバ等を配置しないで、WindowsXP(localマシン)にて、C言語またはC++より、PostgreSQL(win版)へ接続し、DB更新をするアプリケーションを作成したいと考えております。
PostgreSQLは、別のJavaアプリケーションから接続し操作しておりますが、その機能をC言語に移植したいというのが目的です。

上記より、開発環境を検討しておりますが、Windowsにおける、C言語+PostgreSQLの文献がなかなか見つからなく、途方に暮れてしまっている状態です。

現在、Borland C++Compiler5.5をコンパイラと考えており、PostgreSQLのVersionは8.2.5です。

大変申し訳ございませんが、C言語からPostgreSQLを操作する方法をご教授頂けますよう宜しくお願い致します。
尚、他のコンパイラであれば可能等、環境の見直しが必要でしたら、併せてご教授頂けますと幸いです。

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

A 回答 (1件)

ODBCドライバを別途用意してそれ経由で操作するか、あるいは


用意されているC用のインターフェースを使うかになると思いますが

後者は
libpq - C ライブラリ
http://www.postgresql.jp/document/pg825doc/html/ …
サンプルプログラム
http://www.postgresql.jp/document/pg825doc/html/ …
この辺が参考になると思います。

BC++から使うなら、インポートライブラリを自分で作成する必要があるでしょう。

C:\Documents and Settings\All Users\PFiles\PostgreSQL\8.2\lib のディレクトリ

2007/10/27 17:35 <DIR> .
2007/10/27 17:35 <DIR> ..
2007/09/18 12:03 48,620 libecpg.a
2007/09/18 12:03 62,828 libecpg.dll
2007/09/18 12:04 26,430 libecpg_compat.a
2007/09/18 12:04 15,908 libecpg_compat.dll
2007/09/18 12:01 57,074 libpgport.a
2007/09/18 12:03 50,374 libpgtypes.a
2007/09/18 12:03 63,566 libpgtypes.dll
2007/09/18 12:02 3,507,918 libpostgres.a
2007/09/18 12:03 86,800 libpq.a
2007/10/27 17:35 <DIR> ms
2007/10/27 17:35 <DIR> pgxs
9 個のファイル 3,919,518 バイト
4 個のディレクトリ 109,672,783,872 バイトの空き領域

C:\Documents and Settings\All Users\PFiles\PostgreSQL\8.2\lib>dir ms
ドライブ C のボリューム ラベルがありません。
ボリューム シリアル番号は C0EF-7783 です

C:\Documents and Settings\All Users\PFiles\PostgreSQL\8.2\lib\ms のディレク
トリ

2007/10/27 17:35 <DIR> .
2007/10/27 17:35 <DIR> ..
2007/09/18 14:18 16,214 libecpg.lib
2007/09/18 14:18 27,314 libpq.lib
2 個のファイル 43,528 バイト
2 個のディレクトリ 109,672,783,872 バイトの空き領域

C:\Documents and Settings\All Users\cnv\PFiles\PostgreSQL\8.2\lib>

これはバイナリファイルの配布パッケージの一部ですが、見てのとおり
cygwin用とvc++用のライブラリファイルはありますが、BC++用はありませんので
自分で作らなければなりません。

可能なら
Amazon.co.jp: PostgreSQL 徹底活用ガイド for Windows: 本: 斉藤 浩
http://amazon.jp/dp/4844320998
この本を入手して読むのが手っ取り早いと思います。
ちょっと前の本ですが、バージョン8になってからのものではあるので
それなりに参考にできるかと。

ODBCドライバは
PostgreSQL: File Browser
http://www.postgresql.org/ftp/odbc/versions/dll/

これかな?
    • good
    • 0

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

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

このQ&Aを見た人はこんなQ&Aも見ています

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

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

QVC++2005から postgreSQLを操作したい

VC++2005から postgreSQLを操作したいのですが、何か良いサンプルはありますか?

selectさせたり、insertさせたりしたいです。

できれば直接操作できるものが良いです。

PostgreSQLはバージョン8.2.4か最新版を使います。

Aベストアンサー

http://www.postgresql.jp/document/current/html/libpq-example.html
が参考になると思います。

http://www.postgresql.jp/document/current/html/index.html
の「30章libpq - C ライブラリ」をじっくり読むことをお勧めします。

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カラムサイズの取得

度々の質問で少々気恥ずかしいのですが・・・

先日カラム一覧を取得する方法として、多くのRDBMSではシステムカタログを
参照するのが一般的な方法ということを教えて頂きました。
現在pgAdminIIIを使って、システムカタログの中がどうなっているのか、
色々勉強しているのですが、カラムサイズを取得するにはどこを参照すれば
良いのでしょうか? たとえばvarchar(40)のカラムがあった場合に「40」
という数値を取得したいのですが・・・

どなたかご存知であれば、ご教授下さい。

Aベストアンサー

#1回答者です。

PostgreSQLはデータ型が豊富なためか、システムカタログの参照方法が分かりにくいですね。
表中にシステム用の列も作っており、そのまま定義情報を検索すると、ユーザの定義列と一緒に情報を拾ってしまいます。

#1のSQLから、対応するデータ型の追加、「_bpchar」→「char」といった表示変更をするようにしました。

#1と併せて実行してもらえると、違いが分かりやすいと思います。

select
relname as 表名,
attname as 列名,
attnum as 列番,
case typname
when '_bpchar' then 'char'
when '_varchar' then 'varchar'
when '_date' then 'date'
when '_float8' then 'float8'
when '_int4' then 'integer'
when '_interval' then 'interval'
when '_numeric' then 'numeric'
when '_float4' then 'float4'
when '_int2' then 'smallint'
when '_text' then 'text'
when '_time' then 'time'
when '_timestamp' then 'timestamp'
end as 型,
case typname
when '_bpchar' then atttypmod - 4
when '_varchar' then atttypmod - 4
when '_numeric' then (atttypmod - 4) / 65536
else attlen
end as 長さ,
case typname
when '_numeric' then (atttypmod - 4) % 65536
else 0
end as 小数

from pg_stat_user_tables as a,
pg_attribute as b,
pg_type as c
where schemaname='u1'
and relname='t1'
and a.relid=b.attrelid
and b.attnum>0
and b.atttypid=c.typelem
and substr(typname,1,1)='_'
order by schemaname,relname,attnum;

#1回答者です。

PostgreSQLはデータ型が豊富なためか、システムカタログの参照方法が分かりにくいですね。
表中にシステム用の列も作っており、そのまま定義情報を検索すると、ユーザの定義列と一緒に情報を拾ってしまいます。

#1のSQLから、対応するデータ型の追加、「_bpchar」→「char」といった表示変更をするようにしました。

#1と併せて実行してもらえると、違いが分かりやすいと思います。

select
relname as 表名,
attname as 列名,
attnum as 列番,
case typname
when '_bpc...続きを読む

Qtimestampのデータはどのようにして入力

するのでしょうか?

create table tablex(no serial primary key,time timestamp);

insert into tablex(time) values(?);

において?の部分に入れる文字列のフォーマットはどうなるのでしょうか?

例えば
2005年5月5日5時55分55秒
を入れるにはどうしたらいいのでしょうか?

Aベストアンサー

'2005-05-05 05:55:55'

QCプログラミング内でのPostgreSQLの利用について

Cプログラムでのデータベース接続が出来ない事で質問です。

現在C言語で書いたプログラムがありまして、今まではwindows上でCSVファイルから読み込んで、
新しいファイルに書き込むというような内容のプログラム作っていました。

それを今は

OSをLINUXのRedhat(teratermからアクセス)
読み込むデータファイルをデータベース(Postgresql)

にしてやっています。

何とかDBをインストールして、DBにCSVファイルをコピーした物を作る所までは出来ました。

その後CプログラムでDBを利用する時、色んな設定をしてやらなくてはいけないと思うのですが
まずlibpq-fe.hというものをincludeして使うとは分かったのですが、これがまず見つかりません。

質問(1)
OSの中のファイルを探す時にコマンドで# find ~ -name libpq-fe.hとやったのですが間違っていますか?
ちなみにあるとしたらどこにそのヘッダーファイルはありますか?

質問(2)
インストールした手順としては日本PostgreSQLユーザ会のサイトからソースをダウンロードしてコンパイル、インストールを行いましたが、調べるとrpmと言うものを使ってインストールした人が同じような内容で質問していて、develを入れないとヘッダーファイルが
入らないという記述がありました。

その事は何か関係がありますか?

質問(3)
libpq-fe.hが必要と書きましたが、他にもlibpq.soやlibpq.hと書いてあったりしてそこの所もよく分かりません。


記述が足りなかったらすいません。
ヒントでも良いので宜しくお願いします。

Cプログラムでのデータベース接続が出来ない事で質問です。

現在C言語で書いたプログラムがありまして、今まではwindows上でCSVファイルから読み込んで、
新しいファイルに書き込むというような内容のプログラム作っていました。

それを今は

OSをLINUXのRedhat(teratermからアクセス)
読み込むデータファイルをデータベース(Postgresql)

にしてやっています。

何とかDBをインストールして、DBにCSVファイルをコピーした物を作る所までは出来ました。

その後CプログラムでDBを利用...続きを読む

Aベストアンサー

> ヘッダファイルが見つからないのは探す場所が違うんだろうな、何でだろうな…とか。
ヘッダなりライブラリなりの置き場所には慣例的な決まりがありまして、

/usr/include
/usr/lib

などになります。
黙っていても探してくれるのはそれらのディレクトリだけなので、ほかの場所に置いてあっても探してくれません。ということで別途教えてやる必要があります。

-I ヘッダファイル探索ディレクトリ
-L ライブラリファイル探索ディレクトリ
-l 使うライブラリの名前 libXXX

gcc -I/usr/local/pgsql/include -L/usr/local/pgsql/lib -lpq -o sample sample.c

こんな感じになります。
また、コンパイル&リンクはこれでできますが、そのままだと実行する時に sample が libpq.so の位置を知らないのでエラーになります。これは環境変数で指定できます。

export LD_LIBRARY_PATH=/usr/local/pgsql/lib

この環境変数は設定した以後に起動される「全ての」プログラムに対して影響するので、不毛なトラブルの原因になる場合がありますから注意してください。

> ソースからとパッケージからのインストール何が違うのかとか。

RPM インストール
rpm コマンド一発で全部勝手にやってくれます。そのお手軽さがウリです。ヘッダやライブラリは上記の規定のディレクトリに配置されるので、追加オプション指定は不要になります。
なお、この方法だと、当然ながら当該ホストの「全ての」ユーザがそのインストールの影響を受けることになりますのでその点はご注意ください。

ソースからのインストール
昔はこちらしかありませんでした。各種環境設定は全て自前でやる必要があります。裏で勝手にゴソゴソやられるのは気に入らんとか開発の都合上複数のバージョンを使い分けたいとかいう人向けです。上級者向けと言われるのはそのためです。

> ヘッダファイルが見つからないのは探す場所が違うんだろうな、何でだろうな…とか。
ヘッダなりライブラリなりの置き場所には慣例的な決まりがありまして、

/usr/include
/usr/lib

などになります。
黙っていても探してくれるのはそれらのディレクトリだけなので、ほかの場所に置いてあっても探してくれません。ということで別途教えてやる必要があります。

-I ヘッダファイル探索ディレクトリ
-L ライブラリファイル探索ディレクトリ
-l 使うライブラリの名前 libXXX

gcc -I/usr/local/pgsql/i...続きを読む

Qファイルに記述されている複数のSQL文を一度に実行させたい

こんにちわ。

ファイルに記述されているSQL文を、Linuxのコマンドラインなどから
実行したいと考えています。

ファイルに
insert into DB_NAME(aaa,bbb,ccc) values(111,222,333);
insert into DB_NAME(ddd,eee,fff) values(333,777,222);
insert into DB_NAME(aaa,ttt,ddd) values(111,000,999);
...

などのSQL文が複数行(例えば1000個ほど)記述しているのを用意して
なんかしらの方法で一度に実行させたいのです。

mySQLでは、このようなやり方があるのですが
postgreではどのようにすればいいのか、わかりません。

どなたかご存知の方、よろしくお願い致します。

OSはLinuxです。

Aベストアンサー

#1の方も指摘されている通り、 psql を使えば出来ます。

psql で、-f オプションを使うか、該当のDBに接続して \i コマンドを使えば良いでしょう。
http://www.postgresql.jp/document/pg746doc/html/app-psql.html

SQLが記述されているファイルを insert_data.sql、
DBを testdb としますと
例1)-------------------------------------------------------------
$ psql testdb
Welcome to psql x.x.x, the PostgreSQL interactive terminal.




testdb=> \i insert_data.sql
testdb=> \q
-----------------------------------------------------------------

例2)-------------------------------------------------------------
$ psql testdb -f insert_data.sql
-----------------------------------------------------------------

注) ユーザのDBへのアクセス権によっては -U オプションや -W オプションも必要になります。

#1の方も指摘されている通り、 psql を使えば出来ます。

psql で、-f オプションを使うか、該当のDBに接続して \i コマンドを使えば良いでしょう。
http://www.postgresql.jp/document/pg746doc/html/app-psql.html

SQLが記述されているファイルを insert_data.sql、
DBを testdb としますと
例1)-------------------------------------------------------------
$ psql testdb
Welcome to psql x.x.x, the PostgreSQL interactive terminal.




testdb=> \i insert_data.sql
testdb=> \q...続きを読む

QWindows上で、C言語を使ってMySQLを操作するサンプル

今まで、PerlでMySQLを操作していました。
C言語からMySQLを使う必要が(ホビーですが)あり
今までPerlの敷居の低さに慣れていたのか、C言語でMySQL(Version5)を使いたいのですが、どこから手をつけてよいかわかりません。
スピードを優先しますので、ODBCを使わず直接操作したいのですが、そのあたりも含めてご教授ください。

Aベストアンサー

この辺の話が参考になるかな

UNIX系
http://www.pc-view.net/Network/040213/page33.html

WINDOWD系
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200603/06030040.txt

QEclipseでのJDBCドライバについて

Eclipse3.1でデータベース(mysql)にアクセスするプログラムを作ったのですが下記のエラーが出ます。

java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

これはJDBCドライバのセットアップがうまく出来ていないからなのでしょうか?
またEclipseでは、~.jarというファイルをプロジェクトのWEB-INFのlibフォルダに入れれば使える印象があるのですが、参考書(EclipseのではなくJAVAなどの)などにあるようにTomcatのインストールフォルダ以下common/libに入れて環境変数を変更しないといけないのでしょうか?

ご存知の方教えてください、よろしくお願いします。

Aベストアンサー

WEB-INF以下に入れると実行はできるのですが、エクリプスが.javaファイルをコンパイルすることができません。projectの一覧を右クリックしてpropertyを選択し、ダイアログ右側からJava Build Pathを選択し、タグからLibrariesを選び、Add JARsボタンをおして.jarファイルを登録して下さい。
たぶんこれでコンパイルできるはずです。

Qfatal error LNK1120: 外部参照 1 が未解決です

またわからないことが・・・
教えて下さい。
以下をVC++2005でコンパイルすると、

MSVCRTD.lib(crtexew.obj) : error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。
C:\Documents and Settings\tomato\My Documents\Visual Studio 2005\Projects\a\Debug\a.exe : fatal error LNK1120: 外部参照 1 が未解決です。

と警告がでて通りません。
何のことでしょうか。

#include<stdio.h>
#include<process.h>

struct meibo{
  char name[20];
  char tel[20];
  char address[20];
};

void message( void );
void input( FILE *fp, int cnt , struct meibo *a, int *end );

void main( void )
{
  struct meibo a[20];
  FILE *fp;
  int cnt, end;

  if( (fp=fopen( "meibo.dat", "w" ) ) == NULL ){
    printf( "Can not open the meibo.dat.\n" );
    exit( 1 );
  }

  message();

  fprintf( fp, "番号, 名前, TEL, 住所\n" );
  fflush( fp );

  cnt = 0;
  end = 0;
  while( end == 0 ){
    input( fp, cnt, &a[cnt], &end );
    cnt++;
    fflush( fp );
    if( cnt == 20 ){
      printf( "人数が一杯です.終了します.\n" );
      end = 1;
    }
  }
  fclose( fp );
}

void message( void )
{
  printf( "名前, TEL, 住所, endを入力してください.\n" );
  printf( "継続の時はend=0," );
  printf( "中止の時は,end=1と入力してください.\n" );
}

void input( FILE *fp, int cnt, struct meibo *a, int *end )
{
  printf( "名前-->" );
  scanf( "%s", a->name );
  printf( "TEL -->" );
  scanf( "%s", a->tel );
  printf( "住所-->" );
  scanf( "%s", a->address );
  printf( "Exit? Continue:0 Exit:1 -->" );
  scanf( "%d", end );
  printf( "\n" );
  fprintf( fp, "%2d, %s, %s, %s\n",
    cnt+1, a->name, a->tel, a->address );
}

またわからないことが・・・
教えて下さい。
以下をVC++2005でコンパイルすると、

MSVCRTD.lib(crtexew.obj) : error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。
C:\Documents and Settings\tomato\My Documents\Visual Studio 2005\Projects\a\Debug\a.exe : fatal error LNK1120: 外部参照 1 が未解決です。

と警告がでて通りません。
何のことでしょうか。

#include<stdio.h>
#include<process.h>

struct meibo{
  char name[20];
...続きを読む

Aベストアンサー

http://www.a.math.ryukoku.ac.jp/~hig/course/compsci2_2005/man/faq.html
にある現象と同じではないでしょうか、一度お試しください。

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はメインスレッドで動いているようですが
そのメインスレッドの...続きを読む


人気Q&Aランキング