21

CreateDirectory(). 以前はSTLとBoostのみを使用していたメソッドを含むC++コードがいくつかありますが、最近、<windows.h>検索できるように含める必要がありましたCSIDL_LOCAL_APPDATA

さて、このコード:

filesystem.CreateDirectory(p->Pathname()); // Actually create it...

コンパイルされなくなりました:

error C2039: 'CreateDirectoryA' : is not a member of ...

これは、次のこのマクロに対応しwinbase.hます。

#ifdef UNICODE
#define CreateDirectory  CreateDirectoryW
#else
#define CreateDirectory  CreateDirectoryA
#endif // !UNICODE

プリプロセッサがメソッド呼び出しを再定義しています。この名前の衝突を回避するための可能な方法はありますか?または、CreateDirectory()メソッドの名前を変更する必要がありますか?

4

8 に答える 8

15

CreateDirectoryメソッドの名前を変更するだけでよいでしょう。Windows APIを使用する必要がある場合、Windows.hとの戦いは敗戦です。

ちなみに、windows.hを含めることに一貫性がある場合、これはまだコンパイルされます。(他の場所で問題が発生する可能性がありますが)。

于 2010-02-23T21:09:34.947 に答える
10

#include <windows.h>関数にラップされたCSIDL_LOCAL_APPDATAを検索することを唯一の目的とするモジュールを作成できます。

int get_CSIDL_LOCAL_APPDATA(void)
{
    return CSIDL_LOCAL_APPDATA;
}

ところで、何が起こったのかを理解するためによくやった!

于 2010-02-23T21:24:01.110 に答える
9

#undef CreateDirectory

于 2010-02-23T21:10:07.720 に答える
3

クロスプラットフォームのコードベースに取り組んでいる開発者として、これは問題です。それに対処する唯一の方法は

  • windows.hが-少なくともWindowsビルドでは-普遍的に含まれていることを確認してください。次に、CreateDirectoryマクロがすべてのコンパイル単位で定義され、CreateDirectoryWに普遍的に置き換えられます。プリコンパイル済みヘッダーはこれに最適です

または、それが不快な提案である場合(そしてそれは私にとってです)

  • windows.hの使用法をWindows固有のユーティリティファイルに分離します。基本的な必要な機能をエクスポートするファイルを作成します。ヘッダーファイルは、互換性のあるデータ型を使用する必要がありますが、windows.hのインクルードに依存しません。cpp実装ファイルは(明らかに)windows.hを使用する必要があります。

ユーティリティ関数に競合するシンボルを含むプロジェクトヘッダーファイルを含める必要がある場合は、次のパターンが必要です。

#include <windows.h>
#ifdef CreateDirectory
#undef CreateDirectory
#endif
// etc
#include "some_class_with_CreateDirectory_method.h"
// ...

次に、#undef'd(CreateDirectoryAまたはWなど)を使用しているWindowsAPI関数の非マクロバージョンを明示的に呼び出す必要があります。

于 2010-02-24T08:00:46.950 に答える
1

pushマクロ、undefそれ、そしてpop再びマクロ:

#pragma push_macro("CreateDirectory")
#undef CreateDirectory
void MyClass::CreateDirectory()
{
 // ...
}
#pragma pop_macro("CreateDirectory")
于 2017-01-14T16:23:09.100 に答える
1

のバックアップを取りCreateDirectory、それを定義解除し、カスタムのもので仕事を終えたときに再度定義することができます。

#ifdef CreateDirectory
#define CreateDirectory_Backup CreateDirectory
#undef CreateDirectory
#endif

// ...
// Define and use your own CreateDirectory() here.
// ...

#ifdef CreateDirectory_Backup
#define CreateDirectory CreateDirectory_Backup
#undef CreateDirectory_Backup
#endif
于 2018-08-13T08:34:28.807 に答える
0

名前の競合は通常、インクルードされている特定のヘッダーファイルに起因することに注意してください。それまでは、CreateDirectoryやGetMessageのようなものは可視性に引き込まれず、コードは問題なくコンパイルされます。

このようなインクルードをラッパーヘッダーファイルに分離し、最後に「#undefwhatever」を付けることができます。そうすれば、あなたが持っているどんな名前の衝突もなくなります。もちろん、独自のコードでこれらのマクロを使用する必要がない限り(ええ、非常に可能性が高いです...)

于 2017-02-10T16:21:50.810 に答える
-2
#pragma push_macro("CreateDirectory")

何も機能しない場合は、名前を変更する代わりに、関数に独自の名前空間を使用できます。

于 2010-02-23T22:11:12.500 に答える