0

I'm having trouble resolving this issue around my vectors and strings. I've created a class for reading shaders (OpenGL), but currently not using it anywhere within my program. The problem is when I test my application, I still get an error. The function where I've narrowed down the error is below and if I comment-out the the lines, my application runs as expected (uncommenting lines in relation to sProgram causes error:

#define FOR(q, n) for (int q = 0; q < n; q++)
#define SFOR(q, s, e) for (int q = s; q <= e; q++)
#define RFOR(q, n) for (int q = n; q >= 0; q--)
#define RSFOR(q, s, e) for (int q = s; q >= e; q--)

#define ESZ(elem) (int)elem.size()
...
...
bool GLShader::LoadShader(string sFile, int a_iType)
{
    FILE* fp = fopen(sFile.c_str(), "rt");
    if (!fp)
      return false;

   // Get all lines from a file
   vector<string> sLines;    
   char sLine[255];
   while (fgets(sLine, 255, fp))
      sLines.push_back(sLine);
   fclose(fp);

  // const char** sProgram = new const char*[ESZ(sLines)]; <--- problem with sProgram
  // FOR(i, ESZ(sLines))sProgram[i] = sLines[i].c_str(); 

  uiShader = glCreateShader(a_iType);

 // glShaderSource(uiShader, ESZ(sLines), sProgram, NULL); 
  glCompileShader(uiShader);

 // delete[] sProgram; <--- Error

  int iCompilationStatus;
  glGetShaderiv(uiShader, GL_COMPILE_STATUS, &iCompilationStatus);

  if (iCompilationStatus == GL_FALSE)
    return false;

  iType = a_iType;
  bLoaded = true;

  return 1;
}

This is the error I received:

Error   1   error LNK2019: unresolved external symbol __imp___CrtDbgReportW 
referenced in function "public: class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > & __thiscall 
std::vector<class std::basic_string<char,struct std::char_traits<char>,
class std::allocator<char> >,class std::allocator<class 
std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > 
> >::operator[](unsigned int)" 
(??A?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?
$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std
@@@2@@std@@QAEAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@I@Z)
c:\Users\Me\documents\visual studio 2013\Projects\FooV1\FooV1\Bar.obj

And in the output:

1>------ Build started: Project: FooV1, Configuration: Debug Win32 ------
1>  main.cpp
1>Bar.obj : error LNK2019: unresolved external 
  symbol __imp___CrtDbgReportW referenced in function "public: class 
  std::basic_string<char,struct std::char_traits<char>,class 
  std::allocator<char> > & __thiscall std::vector<class 
  std::basic_string<char,struct std::char_traits<char>,class 
  std::allocator<char> >,class std::allocator<class 
  std::basic_string<char,struct std::char_traits<char>,class 
  std::allocator<char> > > >::operator[](unsigned int)" 
  (??A?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator
  @D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?
  $allocator@D@2@@std@@@2@@std@@QAEAAV?$basic_string@DU?$char_traits
  @D@std@@V?$allocator@D@2@@1@I@Z)
1>c:\users\Me\documents\visual studio 2013\Projects\FooV1\Debug\FooV1.exe : 
  fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
4

1 回答 1

0

glShaderSource不必那么复杂(它不依赖于每行指针,如果你在第 255 个字符上给它一个行拆分,我不确定它是否会是你的代码)。将所有文本放入一个字符串或缓冲区,获取指向它的指针并使用指向该指针的指针调用 glShaderSource。

bool GLShader::LoadShader(string sFile, int a_iType)
{
    std::ifstream isSrc(sFile.c_str(), std::ifstream::in);
    if(!isSrc.good())
        return false;

    std::string sLines = "";
    std::string sLine;

    while (isSrc.good()) {
        std::getline(isSrc, sLine);
        sLines.append(sLine);
    }
    isSrc.close();

    uiShader = glCreateShader(a_iType);

    const char* szSrc = sLines.c_str();
    glShaderSource(uiShader, 1, &szSrc, NULL);

为了好玩和咯咯笑,一个使用内存映射文件 io.

bool GLShader::LoadShader(const std::string& sFile, int a_iType)
{
    bool success = false;

    // Windows implementation.
    HANDLE fileHandle = INVALID_HANDLE_VALUE, mappingHandle = INVALID_HANDLE_VALUE;

    do { // not actually a loop
        fileHandle = CreateFile(sFile.c_str(), FILE_GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
        if (fileHandle == INVALID_HANDLE_VALUE)
            break;

        mappingHandle = CreateFileMapping(fileHandle, nullptr, PAGE_READONLY, 0, 0, nullptr);
        if (mappingHandle == INVALID_HANDLE_VALUE)
            break;

        LPVOID const lpvData = MapViewOfFileEx(mappingHandle, FILE_MAP_READ, 0, 0, 0, nullptr);
        if (!lpvData)
            break;

        /*
            ... other stuff
        */

        const char* pszSrc = static_cast<const char*>(lpvData);
        glShaderSource(uiShader, 1, &pszSrc, nullptr);

        /*
            ... the rest of your code
        */

        success = true;
    } while (false); // never repeat

            // cleanup
    if (mappingHandle != INVALID_HANDLE_VALUE)
        CloseHandle(mappingHandle);
    if (fileHandle != INVALID_HANDLE_VALUE)
        CloseHandle(fileHandle);

    return success;
}
于 2013-11-01T05:35:27.060 回答