How to properly use GetModuleFileName?

VS properly points out that you are using an uninitialized buffer - buffer var is a pointer to WSTR, but it was not initialized with the static buffer, neither it was allocated. Also you should remember that MAX_PATH is often not enough, especially on modern systems with long pathnames.

Since you are using C++, it would be a good practice to use it's features. I can suppose the following code:

vector<wchar_t> pathBuf; 
DWORD copied = 0;
do {
    pathBuf.resize(pathBuf.size()+MAX_PATH);
    copied = GetModuleFileName(0, &pathBuf.at(0), pathBuf.size());
} while( copied >= pathBuf.size() );

pathBuf.resize(copied);

wstring path(pathBuf.begin(),pathBuf.end());

cout << path;

Don't use wstring as buffer directly: it is not defined to have a continuous buffer in every implementation (but usually is)


You need to give it a buffer that can hold some characters;

 wchar_t buffer[MAX_PATH]; 

for example.


This is a general problem with the Win32 API, functions return strings into a buffer of a limited size and you are never sure if your buffer was large enough to hold the whole string. Even MAX_PATH is not a good enough constant for paths these days, as kingsb mentioned.

I tend to use a general helper function for this purpose:

template <typename TChar, typename TStringGetterFunc>
std::basic_string<TChar> GetStringFromWindowsApi( TStringGetterFunc stringGetter, int initialSize = 0 )
{
    if( initialSize <= 0 )
    {
        initialSize = MAX_PATH;
    }

    std::basic_string<TChar> result( initialSize, 0 );
    for(;;)
    {
        auto length = stringGetter( &result[0], result.length() );
        if( length == 0 )
        {
            return std::basic_string<TChar>();
        }

        if( length < result.length() - 1 )
        {
            result.resize( length );
            result.shrink_to_fit();
            return result;
        }

        result.resize( result.length() * 2 );
    }
}

Which for GetModuleFileName can be used like this:

extern HINSTANCE hInstance;

auto moduleName = GetStringFromWindowsApi<TCHAR>( []( TCHAR* buffer, int size )
{
    return GetModuleFileName( hInstance, buffer, size );
} );

Or for LoadString like this:

std::basic_string<TCHAR> LoadResourceString( int id )
{
    return GetStringFromWindowsApi<TCHAR>( [id]( TCHAR* buffer, int size )
    {
        return LoadString( hInstance, id, buffer, size );
    } );
}


And, on a sidenote/addition to my answer below: Sometimes, you want to access a function size_t GetString(char* buf = NULL, size_t bufsize = 0); which will return the necessary buffer size if you call it without any parameters and - if you call it normally - writes up to bufsize characters into buf (or until the end of the string it wants to return, whatever comes first), returning the actual number of chars written. An implementation could look like this:

class GetterClass
{
private:
    size_t String2Buffer(const std::string& string, char* const pBuffer = NULL, size_t size = 0)
    {
        size_t s, length = string.length() + 1;
        if (!pBuffer) return length;
        s = std::min<>(length, size);
        memcpy(pBuffer, string.c_str(), s);
        return s;
    }
public:
    size_t GetterFunc(char* p, size_t len)
    {
        const static std::string s("Hello World!");
        return String2Buffer(s, p, len);
    }
};

This typically happens in class factories that live in DLLs and don't want to exchange complex types like std::string because of memory management. To use the interface, you often end up with ugly code:

GetterClass g;
GetterClass* pg = &g;
std::string s(pg->GetterFunc() - 1, '\0');
pg->GetterFunc(&s[0], s.size());

which sucks for obvious reasons, one being that you can't directly use this in stream insertion. After some procrastination and tearing my hair out, I came up with that almost pornographic solution, at least in terms of template and pointer-to-member-function usage:

template <typename tClass>
struct TypeHelper
{
    typedef size_t(tClass::* MyFunc)(char*, size_t);
    static std::string Get(MyFunc fn, tClass& c)
    {
        size_t len = (c.*fn)(NULL, 0);
        std::string s(len - 1, '\0');
        size_t act = (c.*fn)(&s[0], len - 1);
        assert(act == s.size());
        return s;
    }
};

which can then be used in the following way:

GetterClass Foo;
GetterClass* pFoo = &Foo;
std::string s1 = TypeHelper<GetterClass>::Get(&GetterClass::GetterFunc, Foo); // Class version.
std::string s2 = TypeHelper<GetterClass>::Get(&GetterClass::GetterFunc, *pFoo); // Pointer-to-Instance version.

Still a bit complicated but most of the heavy lifting is hidden behind the scenes.