2013-06-04 3 views
1

В моем текущем проекте есть 2 dll, один называется Engine, а другой называется Graphics. Двигатель связан с графикой. А затем основная программа со ссылками на оба, но использует движок.C++ Общение с ошибкой Dll

В некоторых функциях, как это:

typedef const char* ce_safechar; 
AssimpIntegration::GetData(ce_safechar pFile, ... 

эта ошибка выскакивает: _pFirstBlock == pHead, только после того, как я вышел из функции.

Я видел много разных проблем, и все это, кажется, указывает на строки.

Как я могу избежать такого поведения?

Полнофункциональный при необходимости:

FMESH_DATA AssimpIntegration::GetData(ce_safechar pFile, bool convLeftHanded, int maxSM) 
{ 
    // Create an instance of the Importer class 
    Assimp::Importer importer; 
    // And have it read the given file with some example post processing 
    // Usually - if speed is not the most important aspect for you - you'll 
    // probably to request more post processing than we do in this example. 

    int cls = 0x0; 
    if (convLeftHanded) 
     cls = aiProcess_ConvertToLeftHanded; 

    const aiScene* scene = importer.ReadFile(pFile, aiProcess_GenNormals | aiProcess_FindInstances | aiProcess_CalcTangentSpace | cls | aiProcess_Triangulate ); 

    // If the import failed, report it 
    if (!scene) 
    { 
     char* error = (char*)importer.GetErrorString(); 
     CE_ERROR(error, "Assimp Error"); 
    } 

    // Now we can access the file's contents. 
    Group<MESH_STRUCT> Vertices; 
    Group<DWORD> indices; 

    ////////////////////////////////////////////////////////////////////////////////////////// 
    ///////////////////////////////////PROCESS MESH/////////////////////////////////////////// 
    ////////////////////////////////////////////////////////////////////////////////////////// 

    FMESH_DATA data; 

    if (scene->HasAnimations()) 
    { 
     aiAnimation *anim = scene->mAnimations[0]; 

     FOREACH(anim->mChannels[0]->mNumPositionKeys) 
     { 
      aiVector3D position = anim->mChannels[0]->mPositionKeys[i].mValue; 

      CE_ANIMATIONKEY key; 
      key.position = D3DXVECTOR3(position.x, position.y, position.z); 

      data.Keys.push_back(key); 
     } 
    } 

    D3DXVECTOR3 norms; 
    float tanx, tany, tanz; 
    float bitanx, bitany, bitanz; 

    FOREACH (scene->mNumMeshes) 
    { 
     if (i >= maxSM) 
      continue; 

     aiMesh *mesh = scene->mMeshes[i]; 
     Vertices.group.clear(); 
     indices.group.clear(); //dafuck? 

     if (mesh->HasPositions()) 
     { 
      for (int v = 0; v != mesh->mNumVertices; v++) 
      { 
       norms = D3DXVECTOR3(0,0,0); 
       if (mesh->HasNormals()) 
        norms = D3DXVECTOR3(mesh->mNormals[v].x,mesh->mNormals[v].y,mesh->mNormals[v].z); 

       tanx = tany = tanz = 0; 
       bitanx = bitany = bitanz = 0; 

       if (mesh->HasTangentsAndBitangents()) 
       { 
        tanx = mesh->mTangents[v].x; tany = mesh->mTangents[v].y; tanz = mesh->mTangents[v].z; 
        bitanx = mesh->mBitangents[v].x; bitany = mesh->mBitangents[v].y; bitanz = mesh->mBitangents[v].z; 
       } 

       Vertices.push_back(MESH_STRUCT(
        mesh->mVertices[v].x, 
        mesh->mVertices[v].y, 
        mesh->mVertices[v].z, 
        norms, 
        0, 
        0, 
        tanx, // TANGENTS 
        tany, 
        tanz 
       )); 

       for (int b = 0; b < mesh->mNumBones; b++) 
       { 
        if (b > 4) 
         break; 

        float weight = 0.0f; 

        for (int w = 0; w < mesh->mBones[b]->mNumWeights; w++) 
         if (mesh->mBones[b]->mWeights[w].mVertexId == v) 
          weight = mesh->mBones[b]->mWeights[w].mWeight; 

        Vertices.back().bWeight[b] = weight; 
       } 

       if (mesh->HasTextureCoords(0)) 
       { 
        Vertices.back().U = mesh->mTextureCoords[0][v].x; 
        Vertices.back().V = mesh->mTextureCoords[0][v].y; 
       } 
      } 

      for (int f = 0; f != mesh->mNumFaces; f++) 
      { 
       for (int index = 0; index != mesh->mFaces[f].mNumIndices; index++) 
       { 
        indices.push_back(mesh->mFaces[f].mIndices[index]); 
       } 
      } 
     } 

     data.meshData.push_back(Vertices); 
     data.indices.push_back(indices); 

     // Set the required textures 
     const aiMaterial* pMaterial = scene->mMaterials[mesh->mMaterialIndex]; 

     if (pMaterial->GetTextureCount(aiTextureType_DIFFUSE) > 0) { 
      aiString Path; 

      if (pMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &Path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) { 
       std::string FullPath = Path.data; 

       if (FullPath.find("\\") != string::npos) 
        FullPath = FullPath.substr(FullPath.find_last_of("\\")+1, FullPath.length() - (FullPath.length() - FullPath.find_last_of("\\")-1)); 
       else if (FullPath.find("/") != string::npos) 
        FullPath = FullPath.substr(FullPath.find_last_of("/")+1, FullPath.length() - FullPath.find_last_of("/")-1); 

       string rFile = pFile; 
       string spFile = std::string(pFile); 

       if (spFile.find("\\") != string::npos) 
        rFile = spFile.substr(0, spFile.find_last_of("\\")+1); 
       else 
        rFile = spFile.substr(0, spFile.find_last_of("/")+1); 

       FullPath = rFile + FullPath; 

       data.textures.push_back(FullPath); 
      } 
     } 
     else 
     { 
      data.textures.push_back(""); 
     } 
    } 

    data.scene = scene; 
    return data; 
} 
+0

Ошибка выглядит как повреждение памяти. Какие функции экспортируются/импортируются из DLL? Как и когда они называются? – Inspired

+0

Это одна длинная функция. Можете ли вы свернуть его до меньшего примера, который все еще воспроизводит проблему? –

+0

эта функция определена в графической DLL и вызывается в исполняемом файле, а также в dll engine. –

ответ

1

Вы используете объекты STL в качестве параметров и/или типов функций/методов, которые экспортируют на вашей DLL вернуться.

Пример: вы возвращаете FMESH_DATA. Этот класс/структура имеет объекты STL внутри, как мы можем видеть через линию:

data.Keys.push_back(key); 

Дело здесь: Это не очень хорошая идея, чтобы иметь СТЛ материал экспортируются или импортируются через библиотеки DLL. Это требует, чтобы вызывающая сторона вашей DLL использовала тот же CRT объектов, которые были созданы в DLL.

Но если вы действительно хотите это сделать, вы можете изменить Runtime Library ваших проектов (все они) на многопоточные (/ MD). Затем вы сможете безопасно использовать STL через cliend и DLL.

+0

Это может быть решение, просто подождите, пока я проведу проверку. –

Смежные вопросы