ボタンを押下されたら、データベースにアクセスして取得できた情報を
例えば、テーブル「aaa」の内容がメッセージボックスで表示する方法で
Win32 コンソールアプリケーション =>データベースアクセス
Win フォームアプリケーション =>ボタン押下された時のフォームの状態遷移
結合といいますか、フォームからコンソールを呼ぶ?
データベースの情報を取得するにはどういった処理内容をしたらいいのでしょうか?
ご教授をお願いいたします!
http://park1.wakwak.com/~ima/visualcpp_pgsql2.html
を参考に勉強をしているのですが、今回は別々に作成してしまったので
どうにか取り込めないかご教授願えないでしょうか?
環境は
Visual Stadio 2008 です
コンソールアプリケーション側が結果を標準出力に
出してくれるなら、_popen が使えそう。
> コンソールアプリケーション側が結果を標準出力に
> 出してくれるなら、_popen が使えそう。
そんな関数が有るんですね。
でもMSDNによると
メモ :
_popen 関数を Windows プログラムで使用すると無効なファイル ポインタを返すため、プログラムが無期限に応答を停止する原因になります。_popen は、コンソール アプリケーションでは正しく動作します。入出力をリダイレクトする Windows アプリケーションの作成方法については、Windows SDK の「Creating a Child Process with Redirected Input and Output」を参照してください。
だそうです。
http://msdn.microsoft.com/ja-jp/library/96ayss4b.aspx
...だそうです ^^;
てか、コンソールアプリからDBアクセスやってるとこ引っこ抜いて
Winフォームアプリに持ち込んじゃダメなんだろか。
あるいはライブラリに仕立てちゃダメなんだろか。
"わざわざ"メンドクセーことしてない?
コンソールの出力の取得であれば CreatePipe で作成したパイプを
CreateProcess に渡して結果を読み出す方法もあります。
EXEを分けないならフォームアプリケーションから
DBアクセス部分を直接使えばいいだけですね。
>コンソールの出力の取得であれば CreatePipe で作成したパイプを
>CreateProcess に渡して結果を読み出す方法もあります。
って、maruさんのリンク先にも書かれてましたね(^^;
επιστημηさんの意見に賛成!
EXEのまま、DBアクセス部分をexportするってのもあるかも。
# たしかEXE内の関数も呼び出しできると思ったけど、最近確認していないから実際にできるかどうかは知らない。
>EXEのまま、DBアクセス部分をexportするってのもあるかも。
この方法があるなら是非、やってみたいです!!
今は、επιστημηさんの意見
>コンソールアプリからDBアクセスやってるとこ引っこ抜いて
>Winフォームアプリに持ち込んじゃダメなんだろか。
ってのをやっているのですが
libpq.dllのリンクに失敗してハマってます。
DBにアクセスする際の作ってたコンソールアプリのファイル
依存関係も同じにしてみたりしたのですがなかなか抜け出せてません(T_T)
今度は、subaruさんの
CreatePipe,CreateProcessを使用したものを使ってみようかと思っています
まずは、「CreatePipeって何?」って所からですが....
訂正) 一応,,,
libpq.dll-> libpq.libでした。すみません
> libpq.dllのリンクに失敗してハマってます。
ソコくわしく。
そんだけじゃなんもわからん。
//ボタン押下されたときの処理に
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
const char *conninfo;
PGconn *conn;
PGresult *res;
int nFields;
int i,
j;
//** localhostの"postgres"というDBを予め作成しておく
conninfo = "host=localhost dbname=postgres user=postgres password=postgres";
/* データベースとの接続を確立する */
conn = PQconnectdb(conninfo);
と書き込んで、
フォームアプリのプロジェクト(access)のプロパティ
[構成のプロパティ]−[リンカ]-[入力]-[追加の依存ファイル]にlibpq.lib
と記入。
[ツール]-[オプション]-[プロジェクト及びソリューション]-[VC++ディレクトリ]の中にある実行可能ファイルに
\\D:\PostgreSQL\8.4を環境構築にて$(PATH)を記入
C:\Documents and Settings\test\My Documents\Visual Studio 2008\Projects\access\Debug\
の下にlibpq.dllとかlibpqdll.lib他(.dll)を10個くらい置いてます
コンソールアプリでデータベースにアクセスできているのを確認して
そこで使われていた(.dll)を全部コピペしてみました
自分で分かるのはこれくらいで
他にやっておかなければ行けない事はありますでしょうか?
そしたらどうなっちゃったの?
なにがどのように失敗したの?
コンパイルエラー? リンクエラー? 実行時エラー?
さっぱりわからんよ。
エラーがいっぱいでていて(一例だけ抜粋)以下のような物が・・・
1>リンクしています...
1>access.obj : error LNK2031: "extern "C" void __clrcall PQfinish(struct pg_conn *)" (?PQfinish@@$$J0YMXPAUpg_conn@@@Z) の p/invoke を生成できませんでした。呼び出し規約がメタデータに見つかりません。
1>dbaccess.obj : warning LNK4248: 未解決の typeref トークン (01000022) ('pg_conn') です。イメージを実行できません。
1>dbaccess.obj : error LNK2028: 未解決のトークン (0A000015) "extern "C" void __clrcall PQfinish(struct pg_conn *)" (?PQfinish@@$$J0YMXPAUpg_conn@@@Z) が関数 "private: void __clrcall dbaccess::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@Form1@dbaccess@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z) で参照されました。
1>C:\Documents and Settings\suzuki\My Documents\Visual Studio 2008\Projects\access\Debug\access.exe : fatal error LNK1120: 外部参照 14 が未解決です。
何を言われているのか良く理解できてなくて申し訳ないのですが
>なにがどのように失敗したの?
>コンパイルエラー? リンクエラー? 実行時エラー?
-->リンクエラー?ですかね。
1>コンパイルしています...
1>access.cpp
1>リンクしています...
1>access.obj : error LNK2031: "extern "C" void __clrcall…
になっていたので、コンパイルエラーは切り抜けているかと
.exeも出来上がっていなかったので実行時エラーではないかも?
[構成のプロパティ]−[リンカ]-[全般]-[追加のライブラリ ディレクトリ]を確認してください。
あなたのおっしゃる「libpq.lib」が入っているディレクトリ
「C:\Documents and Settings\test\My Documents\Visual Studio 2008\Projects\access\Debug\
」へのパスが入っていないのではないでしょうか。
[構成のプロパティ]−[リンカ]-[全般]-[追加のライブラリ ディレクトリ]を確認してください。
あなたのおっしゃる「libpq.lib」が入っているディレクトリ
「C:\Documents and Settings\test\My Documents\Visual Studio 2008\Projects\access\Debug\
」へのパスが入っていないのではないでしょうか。
すいません。
[プロジェクト]→[プロパティ]→[構成プロパティ]→[全般]→[共通言語ランタイムサポート]が/clr:pureになってませんか?/clrに変更すれば、LNK2031エラーについては解決すると思います
ご参考:http://msdn.microsoft.com/ja-jp/library/ms173734.aspx
困ったことがあれば、エラーコードでGoogle検索すると似たような事例が見つかることがありますよ!
タイロン様 ありがとうございました!
リンクエラーが解決しました!
-------------------------------------------------------------
>[追加のライブラリ ディレクトリ]
>[共通言語ランタイムサポート]が/clr:pure
[追加のライブラリ ディレクトリ]が無記入になっており、また[共通言語ランタイムサポート]がご指摘とおり 「/clr:pure」になってました。
------------------------------------------------------------
現在はデバック中にエラーでDBにアクセスしてくれません
([Form1]にbuttumをひとつ作成して、ボタンを押下されるとデータベースにアクセスするようになっています)
ボタンを押下すると、メッセージボックスが表示され(エラー表示)
アプリケーションのコンポーネントでハンドルされていない例外が発生しました。「続行」をクリックすると…
保護されているメモリに読書き操作を行おうとしました…
のようになってしまいました。
どうしたら解決するのか検討もつかないのでいろいろgoogleで探してみます
あいまいな表現で申し訳ありませんでした。
申し訳ありませんが、もう少しご教授ください
-----------------------------------
readData(unsigned long data); //DBアクセス
------------------------------------
テキストボックスに入っている数字(System::String)を取得して
unshigned longに変換する
char str[] = "this->textBox1->Text";
String^ s = gcnew String( str );
char *endptr;
unsigned long ul;
ul = strtoul(str, &endptr, 10);
readData(ul);
MessageBox::Show(this->textBox1->Text);
それで、上記のようなデバックエラーになってしまうのですが
キャストの仕方が間違っているのでしょうか?
> テキストボックスに入っている数字(System::String)を取得して
> unshigned longに変換する
どう見ても "this->textBox1->Text" を数値に変換
(当然失敗)してるようにしか思えないのですけど。
>デバックエラー
とは?
(デバッグですし)
>char str[] = "this->textBox1->Text";
何をしたいのでしょうか?これだと、
this->textBox1->Text
という文字列になりますよ。(this->textBox1->Textの値ではない)
int i = 10;
char str[] = "i";
と同じ。
>ul = strtoul(str, &endptr, 10);
this->textBox1->Textの値を数値で取りたいのであれば、UInt32::TryParseあたりで変換してください。
ちゃんとエラー処理できますし。
# unsigned long は UInt32でよかったけ?
> ul = strtoul(str, &endptr, 10);
これは何をやりたいのでしょうか??
strtoulって数値の入った文字列を数値に変換する関数なんですけど
(数値以外の文字が入ったらその文字の前までを変換)。
例) "10sec"→10
ま、↓こんなトコすかね。
using namespace System;
int main() {
String^ str = L"123"; // 変換対象文字列
UInt32 val;
if ( UInt32::TryParse(str,val) ) {
unsigned long ul = val;
Console::WriteLine((UInt32)ul);
} else {
Console::WriteLine("conversion failure.");
}
}
テキストボックスに
"11112222"と記入しその記入された'文字'を取得してを自作関数readData(unsigned long deta)に渡す処理だったので
みぃ様のご指摘通り
>文字列を数値に変換
したかったので見よう見まねでキャストしてみました
Blue 様の
>this->textBox1->Textの値を数値で取りたいのであれば、UInt32::TryParseあたりで変換してください。
>ちゃんとエラー処理できますし。
これ!やりたかったんです。
http://imagingsolution.blog107.fc2.com/blog-entry-36.html
を真似てParseでつくってたんですが、
using namespace Systemのメンバではない?エラーが出て
何のクラスなのかなのか調べきれなくて断念して、
strtoul()を使えるように型変換を繰り返してました
>デバックエラー
とは?
実は、データベースにアクセスしているところで接続できていなかったようで
-----------------------------------
readData(unsigned long data); //DBアクセス
------------------------------------
の入り口にデータベース接続部を書いているのですが
その部分でデバックエラーだったようでした
conninfo = "host=localhost dbname=postgres user=postgres password=postgres";
conn = PQconnectdb(conninfo);
--> if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr,
"Connection to database failed: %s",PQerrorMessage(conn));
exit_nicely(conn);
}
ブレークポイントの使い方が分かっていなくてさっき教わり
どうやら
if (PQstatus(conn) != CONNECTION_OK)に入っていっているのを
確認しました。
コンソールでは、接続できていたんですが
まだリンクのし忘れてる部分でもあるのでしょうか?
実行できているならリンクエラーはありません。
# DLLの実行時loadでもやってない限り。
で、エラー・メッセージ:PQerrorMessage(conn) は何と言ってるんですか?
重ね重ね申し訳ありません
本当にありがとうございます
>エラー・メッセージ:PQerrorMessage(conn) は何と言ってるんですか?
「子を評価できません」になっていて
connに入っているのは、0x004D1CB8みたいです。
PQerrorMessage(conn) に到達するまでステップ実行しましたか?
>PQerrorMessage(conn) に到達するまでステップ実行しましたか?
ステップ実行とは(F10)を押したり、関数なら(F11)で関数の中の
ステップに入っていたりですよね?
PQstatusは以下のようにするとifの中に入ってしまいました
if (PQstatus(conn) == CONNECTION_BAD)
{
fprintf(stderr, "Connection to database failed: %s",
PQerrorMessage(conn));
exit_nicely(conn);
}
流れ的には、
Form1で
textBox1に何か数字を記入してもらう
button1を押下したら取得した文字列を数字に変換して
データベースにアクセスしに行く
/* ******************************************************* */
int getData(unsigned long uid, char* status){
int ret;
ret =readData (code, "'OK'");
if( ret == 1 ){
printf("detabase error status\n");
return 1;
}
printf("readData() completed successfully!\n");
return 0;
}
/* ******************************************************* */
int readData(unsigned long code, char * status)
{
const char *conninfo;
PGconn *conn;
PGresult *res;
conninfo = "hostaddr=localhost dbname=firmo01
port=5432 user=postgres password=postgres";
conn = PQconnectdb(conninfo);
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s",
PQerrorMessage(conn));
exit_nicely(conn);
}
/* ******************************************************* */
//ボタン押下時の処理
private: System::Void button1_Click(System::Object^sender,System::EventArgs^ e)
{
char *endptr;
unsigned long figure;
String ^str;
char buf[255];
memset(buf, 0, 255);
str = this->textBox1->Text;
sprintf_s(buf, 100, "%s", str);
figure = strtoul(buf, &endptr, 10);
getData(figure,"'OK'");
}
だーかーらー...
エラー・メッセージ:PQerrorMessage(conn) は何と言ってるんですか?
すみませんっ
PQerrorMessageの使い方が間違えてました
"ERROR : PQconnectdb() -unknown option 'hostaddr'"
と表示されてました
メッセージそのままでは?
hostaddrなんてオプションは知らない,といっているのですから,そこが間違いなのでしょう。
実際,2009/09/07(月) 10:20:00投稿分のコードでは,conninfoにhostaddrという文字列が見受けられます。
おそらく,hostと書くべきなのだと思いますが……。
> str = this->textBox1->Text;
> sprintf_s(buf, 100, "%s", str);
>
> figure = strtoul(buf, &endptr, 10);
結局 UInt32::TryParse使ってないのか、、、
sprintf_sで%sがSystem::Stringに対応しているってMSDNに書いてあったけ?
> sprintf_sで%sがSystem::Stringに対応しているってMSDNに書いてあったけ?
可変長引数は引数の型チェックを素通りするから、
エラー出なくてうまくいってる"つもり"なだけかもー。
>おそらく,hostと書くべきなのだと思いますが……。
hostとした場合は、
fe_sendauth : authentication type 5 not supported
になってしまいました
http://www.ezms.net/guide/util/cse_trouble_20060728_001.html
に乗っていた方法を試してみたら一応接続をするようになれました
CSEが"MD5"非対応だった?って事からかも・・・?
一応接続したんですが
そのあと
すぐ、デバッグが途中で止まってしまうので強制解除?
なので
>UInt32::TryParse
にて書き直してみます。
επιστημη様の
TryParseに変更してデバックしたら動くようになりました!
本当に皆様いろいろありがとうございました
ツイート | ![]() |