DLL usage problem

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • DLL usage problem

      First of all, thank you Nebuchadnezzar for your help with my previous question. I got the Win32 Sys Prog 2nd book, and now have made the shared memory "volatile" and have create an event with the waitforsingleobject to control the thread. It works well.

      I am having a new problem now. I want to create a DLL that has several common functions that DX programs will use. I added a function to it to load an Xfile, extract the textures and materials, add normals to the mesh, and optimize it.

      My game runs fine until I exit. Then during the cleanup phase it bombs with an exception when it tries to delete the first class object that contains the first mesh. I traced it through the destructors. But it bombs in the dbgheap.c:

      Source Code

      1. #else /* WINHEAP */
      2. /*
      3. * Go through the heap regions and see if the pointer lies within one
      4. * of the regions of the local heap.
      5. *
      6. * Pointers from non-local heaps cannot be handled. For example, a
      7. * non-local pointer may come from a DLL that has the CRT linked-in.
      8. *
      9. */
      10. for (i = 0; (base = _heap_regions[i]._regbase) != NULL &&
      11. i < _HEAP_REGIONMAX; i++)
      12. {
      13. if (pUserData >= base && pUserData <
      14. (void *)(((char *)base)+_heap_regions[i]._currsize))
      15. return TRUE;
      16. }
      17. return FALSE;
      18. #endif /* WINHEAP */
      19. --> } (THE GREEN POINTER IS HERE)
      Display All


      If I put the exact same code in a function, instead of the DLL, I get no errors. So, it is only with the DLL function call that I get the problem.

      What would be unique with the DLL memory management that could cause this? It seems to be a heap issue. I tried allocating memory for some strings with "new" instead of just as static in size, but no difference.

      Oh, and I don't get any problems with the small test program I wrote to test/debug the DLL code. I only get it when I use the DLL in my game.

      The second thread is not started until after the DLL has been used to create the meshes for the game.

      Thanks.
    • RE: DLL usage problem

      I have attempted to trace it through every instruction being executed on the exit. It goes to the destructor of the derived class and executes the release of the textures, but there are no textures for that mesh, so it really does nothing. Then it hits the end of that destructor and I have a breakpoint at the beginning of the destructor in the base class, but it doesn't get there. It gets that error and stops there.

      I am baffled. :baby:

      I have been reading all the books I have on memory management. No clue.

      The post was edited 1 time, last by GamerRick ().

    • Does it do the same thing with a release build? You may be able to use an assert to catch the error - in other words, assert(test condition); prior to the call that causes the crash. Something odd might be happening.

      Addionally, the problem might be that the memory being cleared isn't "local" to the dll. You might have to leave the cleanup to the main program instead of using common functions in the dll to do it. I don't usually fiddle much with dll's, so I'm not more than 50% sure of that....

      Rich
      "Your job is not to die for your country. Your job is to make some other poor sod die for his."
    • The DLL is only used during initialization to load the xfiles. I have a class (called XFileObject) that contains the resulting mesh and all associated stuff (materials, textures, etc). So, I don't know why the DLL would cause the problem at exit time.

      Source Code

      1. #define EXPORT __declspec (dllexport)
      2. EXPORT HRESULT CALLBACK DXLoadXfile(IDirect3DDevice9* pDevice,
      3. LPWSTR Xfn,
      4. std::vector<D3DMATERIAL9>& XFMtrls,
      5. std::vector<IDirect3DTexture9*>& XFTextures,
      6. ID3DXMesh** ppObjectMesh,
      7. UINT OPTIONS)
      8. {
      9. HRESULT hr;
      10. ID3DXMesh* ObjectMesh = NULL;
      11. const UINT TpathL = 259;
      12. const UINT UFnL = 100;
      13. TCHAR Tpath[260];
      14. TCHAR UFn[200];
      15. TCHAR CurrPath[260];
      16. DWORD CPL = GetCurrentDirectory(259, CurrPath); // save current directory
      17. if (CPL == NULL)
      18. return E_FAIL;
      19. size_t FnLength;
      20. ID3DXBuffer* adjBuffer = 0; // buffer for adjacency info
      21. ID3DXBuffer* mtrlBuffer = 0; // buffer for materials
      22. DWORD numMtrls = 0;
      23. hr = D3DXLoadMeshFromX(
      24. Xfn, // Xfile to load
      25. D3DXMESH_MANAGED,
      26. pDevice,
      27. &adjBuffer, // Pointer to adjacency buffer
      28. &mtrlBuffer, // Pointer to material buffer
      29. 0, // effect instances (unused)
      30. &numMtrls, // Number of materials
      31. &ObjectMesh); // ID3DXMesh
      32. if (FAILED(hr))
      33. return hr;
      34. if ((OPTIONS & OPT_TEXSAMEASX) != 0) // Use path from xfile
      35. {
      36. hr = StringCchLength(Xfn, TpathL, &FnLength);
      37. if (FAILED(hr))
      38. return hr;
      39. // Save path of xfile to use for textures
      40. hr = StringCchCopy(Tpath, FnLength + 1, Xfn);
      41. if (FAILED(hr))
      42. return hr;
      43. size_t pos;
      44. for ( pos = FnLength; pos > 0; pos-- )
      45. {
      46. if (Tpath[pos] == '\\')
      47. break;
      48. }
      49. if (pos > 0)
      50. Tpath[pos+1] = NULL;
      51. else
      52. Tpath[0] = NULL; // there is no path
      53. SetCurrentDirectory(Tpath);
      54. }
      55. ID3DXBuffer* errors = 0;
      56. DWORD* Tadj = static_cast<DWORD*>(adjBuffer->GetBufferPointer());
      57. hr = D3DXValidMesh(ObjectMesh, (DWORD*) adjBuffer->GetBufferPointer(), &errors);
      58. SAFE_RELEASE(errors);
      59. ID3DXMesh* TMesh = NULL;
      60. if (FAILED(hr))
      61. {
      62. try
      63. {
      64. if (hr == D3DXERR_INVALIDMESH)
      65. {
      66. hr = D3DXCleanMesh(D3DXCLEAN_SIMPLIFICATION,
      67. ObjectMesh, Tadj, &TMesh,
      68. Tadj,
      69. &errors);
      70. if( errors )
      71. {
      72. MessageBoxA(0, (char*)errors->GetBufferPointer(), 0, 0);
      73. throw hr;
      74. }
      75. if (FAILED(hr))
      76. {
      77. MessageBox(0, L"D3DXCleanMesh - Failed", L"ERROR", 0);
      78. throw hr;
      79. }
      80. ObjectMesh->Release();
      81. ObjectMesh = TMesh;
      82. TMesh = NULL;
      83. }
      84. else
      85. throw hr;
      86. }
      87. catch (HRESULT hr)
      88. {
      89. SAFE_RELEASE(errors);
      90. SAFE_RELEASE(adjBuffer);
      91. SAFE_RELEASE(ObjectMesh);
      92. SAFE_RELEASE(TMesh);
      93. return hr;
      94. }
      95. }
      96. try
      97. {
      98. if( mtrlBuffer != 0 && numMtrls != 0 )
      99. {
      100. D3DXMATERIAL* mtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();
      101. for(DWORD i = 0; i < numMtrls; i++)
      102. {
      103. // the MatD3D property doesn't have an ambient value set
      104. // when its loaded, so set it now:
      105. mtrls[i].MatD3D.Ambient = mtrls[i].MatD3D.Diffuse;
      106. // save the ith material
      107. XFMtrls.push_back( mtrls[i].MatD3D );
      108. // check if the ith material has an associative texture
      109. if( mtrls[i].pTextureFilename != NULL )
      110. {
      111. size_t cc;
      112. hr = StringCchLengthA(mtrls[i].pTextureFilename, UFnL, &cc);
      113. if (FAILED(hr))
      114. throw E_FAIL;
      115. //size_t cc = mbstowcs(UFn, mtrls[i].pTextureFilename, 99); // convert char* string to UNICODE
      116. int MBL = MultiByteToWideChar(CP_ACP, NULL, mtrls[i].pTextureFilename, int(cc+1),
      117. UFn, UFnL);
      118. if (MBL <= 0 || MBL > UFnL)
      119. throw E_FAIL;
      120. if ((OPTIONS & OPT_TEXSAMEASX) != 0) // Use path from xfile
      121. {
      122. size_t pos = MBL;
      123. TCHAR* pUFn = UFn+MBL; // point to end of file name
      124. while ( pos > 0 && *pUFn != TCHAR('\\'))
      125. {
      126. pos--;
      127. pUFn--;
      128. }
      129. hr = StringCchCopy(Tpath, TpathL, pUFn);
      130. if (FAILED(hr))
      131. throw hr;
      132. }
      133. else // use path and file name from Xfile
      134. {
      135. hr = StringCchCopy(Tpath, TpathL, UFn);
      136. if (FAILED(hr))
      137. throw hr;
      138. }
      139. IDirect3DTexture9* tex = 0;
      140. hr = D3DXCreateTextureFromFile(pDevice,
      141. Tpath,
      142. &tex);
      143. if (FAILED(hr))
      144. throw hr;
      145. // save the loaded texture
      146. XFTextures.push_back( tex );
      147. }
      148. else
      149. {
      150. // no texture for the ith subset
      151. XFTextures.push_back( NULL );
      152. }
      153. } // end for
      154. } // End if materials
      155. }
      156. catch (HRESULT hr)
      157. {
      158. SAFE_RELEASE(mtrlBuffer);
      159. SAFE_RELEASE(adjBuffer);
      160. SAFE_RELEASE(ObjectMesh);
      161. for(UINT i = 0; i < XFTextures.size(); i++)
      162. SAFE_RELEASE(XFTextures[i]);
      163. XFTextures.clear();
      164. XFMtrls.clear();
      165. return hr;
      166. }
      167. SAFE_RELEASE(mtrlBuffer); // done w/ buffer
      168. if ((OPTIONS & OPT_GENNORMALS) != 0)
      169. {
      170. D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
      171. bool hasNormals = false;
      172. hr = ObjectMesh->GetDeclaration(elems);
      173. if (SUCCEEDED(hr))
      174. {
      175. for(int i = 0; i < MAX_FVF_DECL_SIZE; ++i)
      176. {
      177. // Did we reach D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED, 0,0,0}?
      178. if(elems[i].Stream == 0xff)
      179. break;
      180. if( elems[i].Type == D3DDECLTYPE_FLOAT3 &&
      181. elems[i].Usage == D3DDECLUSAGE_NORMAL &&
      182. elems[i].UsageIndex == 0 )
      183. {
      184. hasNormals = true;
      185. break;
      186. }
      187. }
      188. }
      189. else
      190. {
      191. DWORD meshFVF = ObjectMesh->GetFVF();
      192. if ((meshFVF & D3DFVF_NORMAL) == 0)
      193. hasNormals = false;
      194. }
      195. ID3DXMesh* tempMesh = 0;
      196. try
      197. {
      198. if (!hasNormals)
      199. {
      200. hr = ObjectMesh->CloneMeshFVF(D3DXMESH_SYSTEMMEM, D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX2 ,
      201. pDevice, &tempMesh);
      202. if (FAILED(hr))
      203. throw hr;
      204. hr = D3DXComputeNormals(tempMesh, 0);
      205. if (FAILED(hr))
      206. throw hr;
      207. SAFE_RELEASE(ObjectMesh);
      208. ObjectMesh = tempMesh;
      209. tempMesh = NULL;
      210. hr = ObjectMesh->GenerateAdjacency(0.001f, Tadj);
      211. if (SUCCEEDED(hr))
      212. {
      213. hr = ObjectMesh->OptimizeInplace(
      214. D3DXMESHOPT_ATTRSORT |
      215. D3DXMESHOPT_COMPACT |
      216. D3DXMESHOPT_VERTEXCACHE,
      217. Tadj,
      218. 0, 0, 0);
      219. }
      220. if (FAILED(hr))
      221. throw hr;
      222. }
      223. else
      224. {
      225. hr = ObjectMesh->OptimizeInplace(
      226. D3DXMESHOPT_ATTRSORT |
      227. D3DXMESHOPT_COMPACT |
      228. D3DXMESHOPT_VERTEXCACHE,
      229. Tadj,
      230. 0, 0, 0);
      231. if (FAILED(hr))
      232. throw hr;
      233. }
      234. }
      235. catch (HRESULT hr)
      236. {
      237. SAFE_RELEASE(adjBuffer);
      238. SAFE_RELEASE(ObjectMesh);
      239. SAFE_RELEASE(tempMesh);
      240. for(UINT i = 0; i < XFTextures.size(); i++)
      241. SAFE_RELEASE(XFTextures[i]);
      242. XFTextures.clear();
      243. XFMtrls.clear();
      244. return hr;
      245. }
      246. }
      247. SAFE_RELEASE(adjBuffer);
      248. *ppObjectMesh = ObjectMesh;
      249. SetCurrentDirectory(CurrPath);
      250. return hr;
      251. }
      Display All