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

时间:2015-05-25 22:14:43

标签: c++ winapi

当它在main.cpp中时它可以工作,但如果我输入log.cpp,当我用任意数量的参数调用log函数时,会得到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()] = '\0';

            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()] = '\0';

                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);
    }
}

在我把可能性变为可变数量的参数和调用日志(&#34;任何东西&#34;)之前可行的情况,那么这将如何在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()] = '\0';

    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()] = '\0';

        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);

缺少什么?

1 个答案:

答案 0 :(得分:1)

使用当前编译器,除了具有已知类型/值的实例化之外,您无法单独编译模板代码。

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

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

我建议你在标题中保留第一个功能模板,但用

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

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