RSS

COM のプロパティは関数でパラメータとして使えないことがある!

COM オブジェクトのプロパティですが、呼び出し側では「変数」のように扱うことができます。

あるオブジェクトで、FilePath というプロパティがあり、次のように実装してあります。

STDMETHODIMP CBinFile::get_FilePath(BSTR* pVal)
{
  *pVal = m_FileName.Copy();
  return S_OK;
}

リスト1 プロパティ FilePath の実装

呼び出し側では、次のように FilePath の内容を表示したいとします。

  wprintf_s(L"FileName = %s\n", pObj->FilePath);

リスト2 プロパティ FilePath の使用

これは、正しく動作しません。というのは、pObj->FilePath はリスト1のようなメソッドの呼び出しなので、pVal は名前のない一時変数となるためです。

正しく動作させるためには、リスト3のようにスコープ内で変数を宣言し、その変数に一度、プロパティの値を格納します。

  BSTR str = pObj->FilePath;
  wprintf_s(L"FileName = %s\n", str);

リスト3 プロパティ FilePath の使用

 

広告
 
コメントする

投稿者: : 2018/02/25 投稿先 C, VC++, Windows

 

タグ:

C++ で一時オブジェクトの寿命は超短命!

ATL に CComBSTR という BSTR 文字列を扱うクラスがあります。

これは、BSTR のラッパークラスですが、そのインスタンスは BSTR キャスト演算子が適用されて BSTR 型変数に代入できます。

BSTR bstr = CComBSTR(L”Something”);

この文は一見正しそうに見えますし、実際、普通ちゃんと動作します。しかし、CComBSTR(L”Something”) は一時オブジェクトなので、セミコロンのところでデストラクタがコールされます。

オブジェクト自身は、スコープの最後まで残っているので、bstr 自体はこの一時オブジェクトの内容、つまり L”Something” のままになっています。

ただ、この値の使用はデストラクタ実行の後なので、保証されません。

 
コメントする

投稿者: : 2018/02/25 投稿先 C, VC++, Windows

 

Visual Studio 2017 の C++ ビルドで tlb が見つからない

Visual Studio 2017 で C++ ビルドで tlb (Type Library) ファイルが見つからないというエラーがでます。

TLBNotFound

これはリソースファイル (.rc) の tlb ファイルの指定が Visual Studio のバグで間違っているためです。

リソースファイルをコードとして開いて、間違っている個所を修正します。

下の例で、”AxBitField2.tlb” の .tlb の前に不要なスペースが入っているので、手動で削除します。

#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
1 TYPELIB “AxBitField2 .tlb”

 

 

 
コメントする

投稿者: : 2018/02/10 投稿先 VC++

 

Visual Studio 2017 VC++ でリソースを作成すると変な文字列が挿入される

Visual Studio 2017 の Visual C++ のリソース編集を行うと、下のようなエラーが起こることがあります。(RC2135 file not found: 17)

ERROR

原因はよくわかりませんが、リソース (.rc) ファイルをコード表示で開き、223 行のような文字列がないか調べます。

もし、見つかったら削除してビルドしなおすとエラーが消えます。

RESOURCE

 
コメントする

投稿者: : 2018/01/31 投稿先 VC++

 

Visual Studio 2017 で MFC アプリ開発機能を追加するには

Visual Studio 2015 では Visual C++ プロジェクトのテンプレートに MFC アプリ開発が含まれていましたが、Visual Studio 2017 では、なぜか含まれなくなっています。

しかし、後からこのテンプレートを追加することができます。

「新しいプロジェクト」ダイアログを開いて、テンプレートリストの一番下の「Visual Studio インストーラを開く」をクリックします。

New Projects.png

下のようなインストーラが開くので、「概要」の「C++によるデスクトップ開発」のオプションで必要なもの(ここでは「MFCとATLのサポート」)をチェックします。

SDK Installer.jpg

最後に「変更」ボタンをクリックしますが、その前に Visual Studio 2017 は閉じておきます。

インストールが終了したら、Visual Studio 2017 を再起動して、プロジェクトのテンプレートに追加した項目が含まれていることを確認します。

MFC Template

 

 
コメントする

投稿者: : 2018/01/11 投稿先 VC++

 

VC++ で古いソースをコンパイルするとエラーになる件

Visual Studio 2017 で VC++ の空プロジェクトを作成し、そこに古いソースを追加してビルドしてみると、実行がうまくいきません。

古いソースは SJIS で書かれているのですが、 Visual Studio 2017 の VC++ プロジェクトはデフォルトは Unicode です。

プロジェクトのプロパティダイアログを開き、構成プロパティ-全般の中で「文字セット」を「マルチバイト文字を使用する」に変更してビルドしなおすと正常に動作しました。

その他、管理者として Visual Studio を起動しないとエラーになることもあるようです。

 

 

 
コメントする

投稿者: : 2018/01/07 投稿先 VC++

 

VC++ のビルドで必要な Windows.h が見つからない件

Visual Studio 2017 で Visual C++ のプロジェクトを作成してビルドしてみたところ、「Windows.h が見つからない」というエラーが出ました。

どうも、プロジェクトのプロパティページを開いてインクルードパスを見てみると $(IncludePath) という設定になっています。

同様にライブラリパスは $(LibraryPath) になっていました。

どうも、IncludePath の内容が間違っているようです。これを修正すれば直るはずですが、他のプロジェクトに影響が出るかもしれないので、ここはインクルードパスを追加してみました。

C:\Program Files (x86)\Microsoft SDKs\Windows の下にバージョンの異なる SDK フォルダがずらりとあったので、その中から適当なものを選んで Include フォルダのパスを追加しました。

同様に、LibraryPath でもエラーが出るので、同じ SDK のLib フォルダのパスを追加しました。

これで、エラーは消えてコンパイルできました。


 

参考

このIncludePath, LibraryPath はプロジェクトのプロパティでVC++ディレクトリの中のインクルードディレクトリを編集すると表示されるダイアログで確認できます。

IncludePath.png

 

 
コメントする

投稿者: : 2018/01/07 投稿先 VC++, Windows