忍者ブログ

2024
09
19

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

2024/09/19 (Thu.)

2008
10
28

log4cxx on VC8 リリースビルドの問題

log4cxxのリリースビルドで例外が発生する現象があり、使えなかった。
apatch_log4cxxのmlには、同じような問題に遭遇している人もいるようで、
 Log4cxx with VisualC++ 2008 Express Edition - Release issue
で、こことかで落としたプロジェクトを使って見ても、問題は解決しなかった。
ランタイムライブラリが/MDで統一されていないとダメとか色々あるようだが、

log4cxxのスタティックライブラリを作成、リンクでリリースビルドでも
動作するようになった。スタティックライブラリとするには、
1.log4cxxのプロジェクトでlibを生成するように設定する
2.log4cxxのプロジェクトでプリプロに以下を設定(ARPもlibの場合)
LOG4CXX_STATIC
APR_DECLARE_STATIC
APU_DECLARE_STATIC
3.アプリのプロジェクトでプリプロにLOG4CXX_STATICを設定。
これしないとチョーリンクエラー。

Build log4cxx as static library using MS Visual Studio 2003

PR

2008/10/28 (Tue.) Trackback() Comment(0) C++

2008
09
26

log4cxxの関数名の修正

apache-log4cxx-0.10.0\src\main\include\log4cxx\spi\location\location.h
line118くらい


  #if !defined(LOG4CXX_LOCATION)
#if defined(_MSC_VER)
#if _MSC_VER >= 1300
//      #define __LOG4CXX_FUNC__ __FUNCSIG__
      #define __LOG4CXX_FUNC__ __FUNCTION__
#endif
#else
#if defined(__GNUC__)
      #define __LOG4CXX_FUNC__ __PRETTY_FUNCTION__
#endif
#endif
#if !defined(__LOG4CXX_FUNC__)
#define __LOG4CXX_FUNC__ ""
#endif
      #define LOG4CXX_LOCATION ::log4cxx::spi::LocationInfo(__FILE__, \
           __LOG4CXX_FUNC__,                                                         \
           __LINE__)
  #endif

2008/09/26 (Fri.) Trackback() Comment(0) C++

2008
09
26

MFC ソケットの使用時によくある 2 つの誤り

1. support.microsoft.com/kb/185728/ja

OnReceive 通知関数で、Receive 呼び出しを複数回実行する。

CSocket クラスは、すべてのデータが受信されるか完全に送信されるまで CAsyncSocket Receive 呼び出しおよび CAsyncSocket Send 呼び出しをループすることにより、Receive および Send 呼び出しに対してブロッキングを行います。そのため、Csocket および CAysncSocket のソケット タイプはどちらもブロッキング非対応です。ブロッキング非対応のソケットでは、TCP スタックからアプリケーションに FD_READ 通知が送信されて、データがあることが示されます。MFC により、その FD_READ 通知が OnReceive 通知呼び出しに割り当てられます。

Windows ソケットでは、recv 呼び出しの前の FD_READ 通知を無効にするのでない限り、1 つの FD_READ 通知で recv を複数回呼び出すことは避ける必要があります。しかし、CSocket および CAsyncSocket には、通知を無効にするしくみは備わっていません。そのため、Receive 呼び出しは、OnReceive 関数 1 つにつき 1 回だけ実行するようにします。また、データの転送速度が速い環境で、OnReceive 関数内で Receive 呼び出しを複数回実行すると、アプリケーションで FD_READ が認識されなくなり、偽の FD_READ が生成されるか、FD_READ が失われる (ハングする) ことがあります。

CSocket を CArchive および CSocketFile と一緒に使用して、MFC の CObject から派生したオブジェクトを直接受信または送信することができます。しかし、データの転送速度が速い環境では、内部で複数の Receive 呼び出しが生成される可能性があるため、CSocket を CArchive および CSocketFile と一緒に OnReceive 関数内で使用しないようにします。
2. CAsyncSocket::Send 関数を使用する際に、すべてのデータを送信するために必要な回数の Send 呼び出しを実行しない。

非同期の Send 呼び出しを実行してバッファを送信した場合、実行結果には次の 3 とおりがあります。

1. 呼び出しにより、送信バイト数が返され、バッファが完全に送信されます。
2. 呼び出しにより、送信バイト数が返され、バッファの一部が送信されます。
3. 呼び出しにより、WSAEWOULDBLOCK エラーが返され、バッファは送信されません。
2 番目の場合には、すべてのデータが送信されるか、WSAEWOULDBLOCK が発生するまで、プログラムで Send 呼び出しを繰り返す必要があります。

3 番目の場合には、TCP/IP スタックでは、さらにバッファ領域を解放すると、MFC により OnSend 通知関数に割り当てられた FD_WRITE 通知をアプリケーションにディスパッチします。この時点でプログラムは、すべてのデータが送信されるか、WSAEWOULDBLOCK が発生するまでデータを送信し続ける必要があります。

OnReceive または OnSend の外部で、CSocket Receive および CSocket Send を使用する (つまり、デフォルトの何も実行しない OnSend および OnReceive を使用する) 場合には、Receive および Send をループで使用することや、CArchive および CSocketFile と一緒に使用することができます。

2008/09/26 (Fri.) Trackback() Comment(0) 未選択

2008
09
25

CSocket+CSockFile+CArchiveの注意点

CArchive クラスが提供するメンバ関数 IsBufferEmpty は、CSocket クラス専用です。たとえば、バッファに複数のデータ メッセージがある場合は、処理を繰り返してすべてのデータを読み出してバッファを空にする必要があります。バッファを空にしないと、次のデータ受信通知が無期限に遅れることになります。IsBufferEmpty を使うと、すべてのデータを確実に取得できます。

2008/09/25 (Thu.) Trackback() Comment(0) MFC

2008
09
24

MFCでのメモリリークの検出方法

MFCでのメモリリークの検出方法

MSDN HTMLヘルプ Version 4.74.8702 において、キーワードタブから「メモリ割り当ての追跡」にちょっとした情報は載っていますが、実際にどのように書き込んだり使ったりしたらいいのかの例が 見当たりません。具体的には次のようにすれば検出できます。

#ifdef	__AFX_H__            // MFCのウィンドウを使う場合に限定しています
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#endif

以上のコードを、すべてのソースコード (*.cpp) のヘッダファイルをインクルードしたあとに追加します。

とりあえずこれを追加して実行して普通に終了させてみてください。もし、プログラムでメモリリークが起こっているのであれば、次のような出力がアウトプットウィンドウのデバッグの欄に表示されます。
(半角カタカナは全角カタカナに修正してあります)

スレッド 0x624 終了、終了コード 0 (0x0)。
Detected memory leaks!
Dumping objects ->
G:\Projects\DispBMPDoc.cpp(87) : {158} normal block at 0x014D0040, 921602 bytes long.
 Data: <                > 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 
G:\Projects\DispBMPDoc.cpp(86) : {157} normal block at 0x00346E78, 40 bytes long.
 Data: <(               > 28 00 00 00 80 02 00 00 E0 01 00 00 01 00 18 00 
Object dump complete.
スレッド 0x620 終了、終了コード 0 (0x0)。
プログラム 'G:\Projects\Debug\DispBMP.exe' はコード 0 (0x0) で終了しました。

始めてみる場合は、何のことだかさっぱり分からないと思います。意味としては次のようになります。

Detected memory leaks!

メモリリークを検出しました。

Dumping objects ->

メモリリークしたブロックを表示していきます。

G:\Projects\DispBMPDoc.cpp(87) : {158} normal block at 0x014D0040, 921602 bytes long.

G:\Projects\DispBMPDoc.cppというファイルの87行目で割り当てられたブロックです。
プログラムの実行開始から158番目に割り当てられたブロックです。
割り当てられた番地は、0x014D0040番地です。(OSがWin9x、WinNTによっても値が変わってきます)
割り当てられたサイズは、921602 バイトです。

Data: < > 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00

割り当てられていたブロックに入っているデータの先頭部分が表示されます。

Object dump complete.

メモリリークしたブロックの表示が終わりました。

このような感じで表示されるので、とりあえずファイル名と行番号からメモリを割り当てている場所はわかります。
メモリ開放が行われていないはずなので、追加してください。



[つづきはこちら]

2008/09/24 (Wed.) Trackback() Comment(0) MFC

カレンダー

08 2024/09 10
S M T W T F S
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

リンク

カテゴリー

フリーエリア

最新CM

[08/09 VMAXON]

最新記事

最新TB

プロフィール

HN:
No Name Ninja
性別:
非公開

バーコード

RSS

ブログ内検索

アーカイブ

最古記事

アクセス解析

FX NEWS


-外国為替-

コガネモチ