mcrblog

vcpp-ml

2003年08月

4

[vcpp 00061030] Re: メモリマップトファイルでマッピング済みの領域の拡張

Suzukiです。
お返事ありがとうございます。


> <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/createfilemapping.asp>

> には、

> > If this parameter matches the name of an existing named mapping object,
> > the function requests access to the mapping object with the protection
> > specified by flProtect.

> と書いてありますので、他のパラメータは無視されると考えた方が良いのかもしれ
> ません。

なるほど。そうですね。
単に既存のものを与えられた保護属性でOpenしに行くだけに読めますね。

> <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/sharing_files_and_memory.asp>

> などをみると、二つ目以降のプロセスではOpenFileMappingを使うことを推奨して
> いるように見えますし。

このご指摘を受けて
やっぱりCreateが二人いるのはおかしいような気がしてきました。
二人目はOpenFileMappingを行うのが正しいのでしょうね。

とりあえず、その方針で検討してみます。
どうもありがとうございました。
2

[vcpp 00061029] Re: メモリマップトファイルでマッピング済みの領域の拡張


#出張中でしたので、激しく遅いレスです

On Fri, 01 Aug 2003 01:01:38 +0900
"S.Suzuki" <d...@ca2.so-net.ne.jp> wrote:

> (OSのキャッシュサイズの限界を超えてのテストはしていないのですが、、、)
> じつは、テストプログラムをシンプルにして再度腰をすえて実験をしたのですが、
> 結果としては
> 最初のメールの質問1、2ともにNGでした。。。。
> つまり、ノーマルファイル・ページファイルを問わず、2度目に最初の
> マッピングサイズよりも大きい値を指定しても、最初のサイズを越えた
> アクセスはできませんでした。。。

  拡張できないのはある意味で当然なのかもと言う気がして来まし
た。メモリサイズを拡張するためには現在使っているメモリの後ろ
に連続して開き領域が存在する必要があります。もし後から拡張を
行うのであれば・・・

1.CreateFileMappingで連続した新メモリを確保する。
2.MapViewOfFileで新メモリをマッピング
3.以前の旧メモリから新メモリにデータをコピー。
4.UnmapViewOfFileで旧メモリをアンマップ。
5.CloseHandleで旧メモリを破棄。
6.全プロセスでMapViewOfFileを使い再度アドレスを取得。

  と言うステップを各プロセスに排他をかけた状態で行はなくては
ならないでしょう。MapViewOfFileでメモリアドレスに変換した状
態で確保しているなら、何らかのイベントを全プロセスに通知して
再度メモリアドレスを取得しなおしてもらはないといけないでしょ
うし。

> 結局メモリマップトファイルによる動的なメモリ共有は

  私なら共有メモリに操作を行う部分をDLLにカプセル化。
  上記のようなメモリ拡張操作をDLL内に実装します。

-----------------------------------------------------------
   ヘヘ   ヘヘ       甕星 (Microsoft MVP)
  ミ''ミ ミ..ミ      E-Mail  : m...@abox9.so-net.ne.jp
 ヽ(  )   (  )ζ    
===========================================================
1

[vcpp 00061028] Re: OLE DBでの行の追加更新について

石河@DSKです。DB関係はよく知りません。

田口 和明 <t...@head.hitachi-hec.co.jp> schrieb:
> 5バイト以下の文字列の登録更新ではエラーとなりません。列のサイズと同
         ~~~~
「未満」ですね?

> じサイズの文字列を登録更新しようとすると、エラーとなってしまいます。

> いろいろ調べてはみたのですが、解決できませんでした。

何を調べて、どんなことを試したのですか?

>     strcpy(dbTable.m_AAA, "12345");     
>     hr = dbTable.Insert();  // <-- DB_E_ERRORSOCCURREDとなる

strcpy()だと'\0'が書き込まれるからじゃないでしょうか。strncpy()だとど
うでしょう。
ところでいつも思うのですが、他人が書いたロクにコメントも入っていないソー
スを、仕事でもないのに見る気になりますか? と小一時間(以下略)

Tschuess!
 ∧ ∧  ∩ 半ばは自己の幸せを、半ばは他人の幸せを
(・o・)_||
 |     | 石河(was 井島) 正@電算システム
 ∪ ̄∪∪ ̄∪ i...@densan-s.co.jp
  野獣之図
1

[vcpp 00061027] OLE DBでの行の追加更新について

田口と申します。

OLE DBの使い方で質問があります。

Oracleに対して、OLE DBを使用してアクセスするプログラムを作成している
のですが、Oracle用のOLE DB Providerで、MSの MSDAORA とOracleの 
OraOLEDB で行の登録更新の動作が異なり、解決策が見出せず苦戦しており
ます。OLE DBは今回初めて使用するためまだよく理解していません。どなた
か、ご教授願えないでしょうか。

テーブルに、列名:AAA 型:varchar2(5)の列があります(5バイトの文字列)。
この列に5バイトの文字列を登録更新しようとすると、MSDAORAでは問題ない
のですが、OraOLEDBだとエラーとなってしまいます。
行の登録更新には、CRowsetクラスのInsert()とSetData()を使用しているの
ですが、これらが、DB_E_ERRORSOCCURRED (0x80040E21)を返してきます。
5バイト以下の文字列の登録更新ではエラーとなりません。列のサイズと同
じサイズの文字列を登録更新しようとすると、エラーとなってしまいます。

いろいろ調べてはみたのですが、解決できませんでした。
OraOLEDBの問題なのか、私のコーディングの問題なのか...
多分後者でしょう、私のOLE DBの使い方が未熟なんだと思います。
OLE DBの使い方でプロパティの設定など、まだ足らないところがあるのでしょ
うか?
よろしくお願いします。

#include <atlbase.h>
#include <atldbcli.h>
#include <atldbsch.h>
#include <comdef.h>

class CTestTable
{
public:
    char m_AAA[6];

    BEGIN_COLUMN_MAP(CTestTable)
        COLUMN_ENTRY(1, m_AAA);
    END_COLUMN_MAP()
};
void main()
{
    CoInitialize(NULL);
    HRESULT hr;
    CDataSource dbSource;
    CSession dbSession;
    CCommand <CAccessor<CTestTable> > dbTable;
    
    // OraOLEDB
    hr = dbSource.OpenFromInitializationString(
          (BSTR)CComBSTR(L"Provider=OraOLEDB.Oracle.1; \
                Password=aaa;User ID=bbb;Data Source=ccc"));    
    // MSDAORA
//    hr = dbSource.OpenFromInitializationString(
//            (BSTR)CComBSTR(L"Provider=MSDAORA.1; \
//                Password=aaa;User ID=bbb;Data Source=ccc"));
    hr = dbSession.Open(dbSource);

    CDBPropSet PropSet(DBPROPSET_ROWSET);
    PropSet.AddProperty(DBPROP_CANFETCHBACKWARDS, true);
    PropSet.AddProperty(DBPROP_CANSCROLLBACKWARDS, true);
    PropSet.AddProperty(DBPROP_IRowsetChange, true);
    PropSet.AddProperty(DBPROP_UPDATABILITY, \
        DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_INSERT | \
        DBPROPVAL_UP_DELETE);

    hr = dbTable.Open(dbSession, "select aaa from test", &PropSet);
    strcpy(dbTable.m_AAA, "12345");     
    hr = dbTable.Insert();  // <-- DB_E_ERRORSOCCURREDとなる

    dbTable.Close();
    dbSession.Close();
    dbSource.Close();
    CoUninitialize();
}
1

[vcpp 00061026] Re: メモリマップトファイルでマッピング済みの領域の拡張

中村です。

At 01 Aug 2003 01:01:38 +0900 S.Suzuki wrote:
> 最初のプロセス100バイト。後から別のプロセスが5000バイトをマッピング
> すると、後のプロセスが、4097バイト目をアクセスした時点で
> 不正なアクセスで落ちてしまいます(ノーマルファイルでもページファイルでも)。
> 最初の100バイトは確かに超えていますが、おそらくページサイズ単位で
> マッピングされているので、2回目の5000バイト(2ページ分)は
> 正しくマッピングされていないということだと思います。
> #ちなみにノーマルファイルの場合、フォルダー上のファイルサイズ自体は
>   ちゃんと5000バイトになっているのですが。。。

> <勝手な予想>
> CreateFileMappingのサイズの指定は、一番最初に
> 行ったときだけ有効で、後から同じマッピングの名前を指定した場合は
> 最初の値が適用されるだけで、サイズの指定に意味はないのではないか?
> (最初より小さい場合は有効かもしれませんが)
> と考えています。
> </勝手な予想>

<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/createfilemapping.asp>

には、

> If this parameter matches the name of an existing named mapping object,
> the function requests access to the mapping object with the protection
> specified by flProtect.

と書いてありますので、他のパラメータは無視されると考えた方が良いのかもしれ
ません。

<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/sharing_files_and_memory.asp>

などをみると、二つ目以降のプロセスではOpenFileMappingを使うことを推奨して
いるように見えますし。

しかし、ファイルのサイズが増えてしまうのはなぜなんでしょう。そっちがバグな
のかもしれませんね。


-- 
Satoshi Nakamura <s...@zak.att.ne.jp>
記事検索
Amazon.co.jp
  • ライブドアブログ