RSS

カテゴリー別アーカイブ: VC++

Visual Studio 2017 Visual C++ で Boost Class Library を使うときのリンクエラー

Visual Studio 2017 Visual C++ で Boost Class Library を使うとき、下のようなリンクエラー (LNK1104) が出ることがあります。

Boost Class Library には、ヘッダーオンリーのパッケージとビルドされた(Lib が作成される)パッケージがあり、後者の場合にこのようなエラーが発生することがあります。

Error_vc141

これは、インストールされている Boost のバージョンまたはビルドした Visual C++ のバージョン、x86 でない等などが正確に一致していないためです。

「ツール/NuGetパッケージマネージャ/ソリューションのNuGetパッケージの管理」メニューから、正確な Boost パッケージをインストールしなおします。

 

広告
 
コメントする

投稿者: : 2018/03/09 投稿先 VC++

 

Visual Studio 2017 Visual C++ で Boost Class Library を使う場合 C4996 エラー

Visual Studio 2017 Visual C++ で Boost Class Library を使う場合、C4996 というエラーが発生してビルドできないケースがあります。

これは、Security Development Lifecycle (SDL) のチェックのために発生するエラーです。

これを抑制するには、プロジェクトのプロパティダイアログを開き、C/C++全般の中の「SDL チェック」を「いいえ」に設定します。

SDL_Error_C4996

なお、C4996 はエラーなので #pragma warning(disable:4996) は効きません。

 

 
コメントする

投稿者: : 2018/03/08 投稿先 VC++

 

Visual C++ 2017 で アセンブラ出力を行うには

プロジェクトのプロパティを開き、「C/C++ のすべてのオプション」を選択します。

「オプションまたはスイッチの検索」で /FA などと入れてみる。(/FA はアセンブリコードのみを出力するオプション)

フィルタ結果が表示されるので、「アセンブリの出力」に /FA などと入れてダイアログを閉じる。オプションの詳細は次の MSDN の記事を参照。
出力ファイルのオプション

ビルドしなおすと .asm ファイルが Debug フォルダにできているはずである。

VC2017AsmOutput

 
コメントする

投稿者: : 2018/03/06 投稿先 VC++

 

タグ:

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

 

タグ: