1. ホーム
  2. c++

[解決済み] SHGetKnownFolderPath()関数を動作させることができない

2022-02-12 13:54:10

質問

SHGetKnownFolderPath()関数の使用で困っています。 次のようなエラーメッセージが表示されます。 Type error in argument 1 to 'SHGetKnownFolderPath'; expected 'const struct _GUID *' but found 'struct _GUID'.

において KnowFolders.h は、以下の関連する定義があります。

#define DEFINE_KNOWN_FOLDER(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
    EXTERN_C const GUID name
...
DEFINE_KNOWN_FOLDER(FOLDERID_ProgramFiles,0x905e63b6,0xc1bf,0x494e,0xb2,0x9c,0x65,0xb7,0x32,0xd3,0xd2,0x1a);

私はPelles Cコンパイラを使用しています。

これは私のサンプルコードです。

#include <windows.h>
#include <wchar.h>
#include <KnownFolders.h>
#include <shlobj.h>

int wmain(int argc, wchar_t **argv) {

    PWSTR path = NULL;

    HRESULT hr = SHGetKnownFolderPath(FOLDERID_ProgramFiles, 0, NULL, &path);    

    if (SUCCEEDED(hr)){

        wprintf(L"%ls", path);
    }

    CoTaskMemFree(path);

    return 0;
}

このエラーメッセージを修正するには?

EDIT SHGetKnownFolderPath()を使ったコード例を見ましたが、いずれも は、ポインタなしで関数を実行します。例えば、以下のようなものです。

hr = SHGetKnownFolderPath(FOLDERID_Public, 0, NULL, &pszPath);
if (SUCCEEDED(hr))
{
    wprintf(L"FOLDERID_Public: %s\n", pszPath);
    CoTaskMemFree(pszPath);
}

CppShellKnownFolders.cpp

解決方法は?

Jonathan Potter氏のコメントを参考にさせていただきました。 を修正しました。

問題は非常に微妙なものでした。次のコード行は、C言語のように見えますが は、C++である。

HRESULT hr = SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &path);

SHGetKnownFolderPath() 関数は以下のプロトタイプを持つ。

STDAPI SHGetKnownFolderPath(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR*);

最初の引数は REFKNOWNFOLDERID .

shtypes.h ファイルには、次のように書かれています。

#ifdef __cplusplus
#define REFKNOWNFOLDERID const KNOWNFOLDERID &
#else
#define REFKNOWNFOLDERID const KNOWNFOLDERID * /*__MIDL_CONST*/
#endif /* __cplusplus */

これはつまり、C++では REFKNOWNFOLDERID は参照で、C はポインタです。その結果、C++ではアンパサンドは不要になります。 のコードで、最初のパラメータを指定します。 Visual C++では、CコードはC++と一緒にコンパイルされることが多く、その区別は というように、両言語の区別が曖昧になることがよくあります。

2つ目の問題である Unresolved external symbol 'FOLDERID_ProgramFiles'. error. を追加することで、エラーが修正されます。 #include <initguid.h> の前に #include <ShlObj.h> . その理由は、次のように説明されています。 記事 .

そこで、以下のコードをPelles Cでコンパイルしてみました。

#include <windows.h>
#include <initguid.h>
#include <KnownFolders.h>
#include <ShlObj.h>
#include <wchar.h>

int wmain(void) {

    PWSTR path = NULL;

    HRESULT hr = SHGetKnownFolderPath(&FOLDERID_Documents, 0, NULL, &path);

    if (SUCCEEDED(hr)) {
        wprintf(L"%ls\n", path);
    }

    CoTaskMemFree(path);

    return 0;
}