RSS

月別アーカイブ: 2月 2018

COM DLL を VC++ アプリで使う場合の決まった書き方

COM DLL を VC++ のコンソールアプリで使う場合の決まった書き方をリスト1に示します。

// TestAxStrFuncs.cpp : アプリケーションのエントリ ポイントを定義します。
//
#include "stdafx.h"
#import "C:\lib\AxStrFuncs.tlb" named_guids no_namespace

int main()
{
  // COM の初期化のため必要
  CoInitialize(NULL);

  // COM オブジェクトを定義
  CComPtr<IStrFuncObject> pObj;

  // COM オブジェクトを作成
  HRESULT hr = pObj.CoCreateInstance(__uuidof(StrFuncObject));

  // プロパティの使用
  printf_s("%d\n", pObj->Version);

  // メソッドの使用
  BSTR str = pObj->Left(L"ABCDEFGHIJK", 5);

  return 0;
}

リスト1 COM DLL を使う場合の決まった書き方の例

stdafx.h には ATL のヘッダーファイルをインクルードしておく必要があります。リスト2では、atlbase.h と atlcom.h がインクルードしてありますが、アプリケーションによっては、他のヘッダーファイルが必要になります。

// stdafx.h : 標準のシステム インクルード ファイルのインクルード ファイル、または
// 参照回数が多く、かつあまり変更されない、プロジェクト専用のインクルード ファイル
// を記述します。
//

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>

// TODO: プログラムに必要な追加ヘッダーをここで参照してください
#include <atlbase.h>
#include <atlcom.h>

リスト2 stdafx.h の例

広告
 
コメントする

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

 

タグ:

ATL ワイド文字・マルチバイト文字変換マクロ

ATL には、ワイド文字 (Unicode) とマルチバイト文字 (SJIS) を相互変換できるマクロが用意されています。詳しい内容は下記 MSDN の記事を参照願います。

MSDN ATL と MFC の文字列変換マクロ

マクロには ATL 7.0 でリリースされたものの他、ATL 3.0 でリリースされた旧マクロもサポートされています。そして、新マクロの方が高機能で制限が少ないです。

旧マクロを使用するときは、

USES_CONVERSION

を事前に実行しておく必要があります。制限の多い旧マクロですが、関数のように使用できます。

マクロ名には規則性があり、次のような文字の組み合わせになっています。

  • C は定数 (Constant) を意味する。
  • A はマルチバイト文字 (ANSI) を意味する。
  • W はワイド文字 (Wide) を意味する。
  • T は TEXT マクロと同じで、プロジェクトの設定により A または W になる。
  • OLE は W と同じである。
  • EX はバッファサイズを指定するとき使用する。

なお、これらのマクロを使用する場合、atlconv.h をインクルードしておく必要があります。

リスト1は、マクロの使用例です。

int main(int argc, char* argv[])
{
  if (argc <= 1)
  {
    // ATL 7.0 Conversion Macro
    CW2A stra(L"ABCD");
    puts(stra);
    CA2W strw("abcd");
    _putws(strw);
  }
  else
  {
    // ATL 3.0 Conversion Macro
    USES_CONVERSION;

    LPCWSTR strW = A2W("XYZ");
    _putws(strW);
    LPCSTR strA = W2A(L"xyz");
    puts(strA);
  }

  getchar();
  return 0;
}

リスト1 マクロの使用例

 
コメントする

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

 

独自簡易ログ関数 (VC++)

日付+メッセージ ATL または MFC 使用

// ログを保存
#include <atlstr.h>
#include <atltime.h>
#define LOGFILE "C:\\Temp\\LogFile.log"
void AddLog(const wchar_t* message)
{
  FILE* fp;
  fopen_s(&fp, LOGFILE, "a");
  CTime tm = CTime::GetCurrentTime();  // UTC
  CString ts = tm.Format(_T("%Y/%m/%d %a %H:%M:%S"));
  fwprintf_s(fp, L"%s: %s\n", ts, message);
  fclose(fp);
}

(注意) atlstr.h, atltime.h をインクルードする必要がある。LOGFILE でログファイルのパスを指定する必要がある。

 

 
コメントする

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

 

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++