C++ Win32 如何将此函数放在单独的 cpp 文件中?

C++ Win32 how can i put this functions on separate cpp file?

当它在 main.cpp 中时它可以工作,但是如果我在 log.cpp 中使用任意数量的参数调用日志函数时会出现 LNK2019 错误。

string getDate()
{
    SYSTEMTIME localTime;

    TCHAR strTime[128];

    GetLocalTime(&localTime);

    wsprintf(strTime, "%04d_%02d_%02d_", localTime.wYear, localTime.wMonth, localTime.wDay);

    stringstream strm;

    strm << strTime;

    string date = strm.str();

    return &date[0];
}

string getHour()
{
    SYSTEMTIME localTime;

    TCHAR strTime[128];

    GetLocalTime(&localTime);

    wsprintf(strTime, "%02d:%02d:%02d >> ", localTime.wHour, localTime.wMinute, localTime.wSecond);

    stringstream strm;

    strm << strTime;

    string hour = strm.str();

    return &hour[0];
}

void addToStream(stringstream& /*a_stream*/)
{
}

template<typename T, typename... Args>
void addToStream(stringstream& a_stream, const T& a_value, Args... a_args)
{
    a_stream << a_value;
    addToStream(a_stream, a_args...);
}

template<typename... Args>
void log(Args... a_args)
{
    stringstream strm;
    addToStream(strm, a_args...);

    string s = strm.str();

    HKEY key;
    char appPath[1024];
    DWORD appPathLength = 1024;

    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\CurrentControlSet\Control\Session Manager\Environment", 0, KEY_READ | KEY_WRITE, &key) != ERROR_SUCCESS)
    {
        RegCloseKey(key);
    }
    else
    {
        if (RegQueryValueEx(key, "SERVIDOR_DIR", NULL, NULL, (LPBYTE)&appPath, &appPathLength) != ERROR_FILE_NOT_FOUND)
        {
            HANDLE hFile;

            string dateProv = getDate();
            char *date = new char[dateProv.size() + 1];
            copy(dateProv.begin(), dateProv.end(), date);
            date[dateProv.size()] = '[=10=]';

            char fileNamePath[MAX_PATH];
            strcpy(fileNamePath, appPath);
            strcat(fileNamePath, "\logs\painel\");
            strcat(fileNamePath, date);
            strcat(fileNamePath, "levaetraz.log");
            puts(fileNamePath);

            hFile = CreateFile(
                fileNamePath,           // file to open
                GENERIC_WRITE,          // open for writing
                0,                      // share for writing
                NULL,                   // default security
                //  CREATE_NEW,         // existing file only
                //CREATE_ALWAYS,        // creates a new file, always.
                OPEN_ALWAYS,            // creates a new file, always.
                FILE_ATTRIBUTE_NORMAL,  // normal file
                NULL                    // no attr. template
                );

            if (hFile != INVALID_HANDLE_VALUE)
            {
                // Write to File
                BOOL bErrorFlag = FALSE;

                string hourProv = getHour();
                char *hour = new char[hourProv.size() + 1];
                copy(hourProv.begin(), hourProv.end(), hour);
                hour[hourProv.size()] = '[=10=]';

                char stringLog[1024];
                strcpy(stringLog, hour);
                strcat(stringLog, &s[0]);
                strcat(stringLog, "\r\n");
                puts(stringLog);

                DWORD dwPtr = SetFilePointer(hFile, 0, NULL, FILE_END); //set pointer position to end file
                DWORD dwBytesToWrite = lstrlen(stringLog);
                DWORD a = 0;

                bErrorFlag = WriteFile(
                    hFile,              // open file handle
                    stringLog,          // start of data to write
                    dwBytesToWrite,     // number of bytes to write
                    &dwPtr,             // number of bytes that were written
                    NULL                // no overlapped structure
                    );

                delete[] hour;
            }

            delete[] date;

            CloseHandle(hFile);

            RegCloseKey(key);
        }
        RegCloseKey(key);
    }
}

在我将参数数量可变和调用 log("any thing") 工作之前,那么这将如何在参数数量可变的 log.cpp 中工作?

void log(char *log)
{
    HANDLE hFile;

    std::string dateProv = getDate();
    char *date = new char[dateProv.size() + 1];
    std::copy(dateProv.begin(), dateProv.end(), date);
    date[dateProv.size()] = '[=11=]';

    char fileNamePath[MAX_PATH];
    strcpy(fileNamePath, "logs/painel/");
    strcat(fileNamePath, date);
    strcat(fileNamePath, "levaetraz.log");
    puts(fileNamePath);

    hFile = CreateFile(
        fileNamePath,           // file to open
        GENERIC_WRITE,          // open for writing
        0,                      // share for writing
        NULL,                   // default security
        //  CREATE_NEW,         // existing file only
        //CREATE_ALWAYS,        // creates a new file, always.
        OPEN_ALWAYS,            // creates a new file, always.
        FILE_ATTRIBUTE_NORMAL,  // normal file
        NULL                    // no attr. template
        );

    if (hFile != INVALID_HANDLE_VALUE)
    {
        // Write to File
        BOOL bErrorFlag = FALSE;

        std::string hourProv = getHour();
        char *hour = new char[hourProv.size() + 1];
        std::copy(hourProv.begin(), hourProv.end(), hour);
        hour[hourProv.size()] = '[=11=]';

        char stringLog[1024];
        strcpy(stringLog, hour);
        strcat(stringLog, log);
        strcat(stringLog, "\r\n");
        puts(stringLog);

        DWORD dwPtr = SetFilePointer(hFile, 0, NULL, FILE_END); //set pointer position to end file
        DWORD dwBytesToWrite = lstrlen(stringLog);
        DWORD a = 0;

        bErrorFlag = WriteFile(
            hFile,              // open file handle
            stringLog,          // start of data to write
            dwBytesToWrite,     // number of bytes to write
            &dwPtr,             // number of bytes that were written
            NULL                // no overlapped structure
            );

        delete[] hour;
    }

    delete[] date;

    CloseHandle(hFile);
}

我创建了一个 log.h 并包含在 main.cpp

#pragma once

template<typename... Args>
void log(Args... a_args);

缺少什么?

使用当前的编译器,除了具有已知 types/values.

的实例化之外,您无法单独编译模板代码

主要问题似乎是这段代码:

template<typename T, typename... Args>
void addToStream(stringstream& a_stream, const T& a_value, Args... a_args)
{
    a_stream << a_value;
    addToStream(a_stream, a_args...);
}

template<typename... Args>
void log(Args... a_args)
{
    stringstream strm;
    addToStream(strm, a_args...);

    string s = strm.str();
    // More stuff

我建议您保留 header 中的第一个功能模板,但将第二个替换为

template<typename... Args>
void log(Args... a_args)
{
    stringstream strm;
    addToStream(strm, a_args...);
    logString( strm.str() );
}

然后您可以单独编译新函数 logString,因为它没有模板化。