   Loading files in C++... (crashing)
  I'm trying to load a saved file in C++. The problem is that I'm calling the DLL from UnrealScript, and don't really have a good way to debugging it. I can only confirm that it makes UDK crash.So... can anyone spot any obvious flaws in my loading code (compiles fine)?// SaveLib.cpp : Defines the exported functions for the DLL application.//#include "stdafx.h"#include <fstream>#include <iostream>#include "OSFDlg.h"using namespace std;extern "C"{__declspec(dllexport) unsigned int SaveGame(wchar_t* LevelName, float X, float Y, float Z, wchar_t* SavePath){wofstream SaveStream(SavePath, ios::out);SaveStream << LevelName;SaveStream << X;SaveStream << Y;SaveStream << Z;SaveStream.close();return 1;}struct Save{wchar_t LevelName;float X, Y, Z;};__declspec(dllexport) Save* LoadGame(wchar_t* LoadPath){wifstream LoadStream(LoadPath, ios::in);static Save *NewSave;NewSave = new Save;LoadStream >> NewSave->LevelName;LoadStream >> NewSave->X;LoadStream >> NewSave->Y;LoadStream >> NewSave->Z;LoadStream.close();return NewSave;}__declspec(dllexport) wchar_t SaveDiag(){//FilterTCHAR szFilter[] = TEXT("Save Files (*.SAV)\0*.sav\0");//Default extensionTCHAR szDefExtension[] = TEXT("sav\0");COSFDialog SaveDiag;if(SaveDiag.FileSaveDlg(szFilter, szDefExtension, NULL)){return (wchar_t)SaveDiag.GetFileName();}}__declspec(dllexport) wchar_t LoadDiag(){//FilterTCHAR szFilter[] = TEXT("Save Files (*.SAV)\0*.sav\0");//Default ExtensionTCHAR szDefExtension[] = TEXT("sav\0");COSFDialog LoadDiag;if(LoadDiag.FileOpenDlg(szFilter, szDefExtension, TEXT("Load Game"), false))return (wchar_t)LoadDiag.GetFileName();}}Edit: It's the LoadGame() function that fails. LoadDiag seems to work fine... it just displays a File Open Dialog.   
  In terms of debugging you can attach to an already running process in Visual Studio. All you really need to do is:-Make the program wait somewhere to give you a chance to attach, something likestatic bool wait = true;while(wait) {}at the top of the crashing function should do it.-Perform the steps to recreate the crash, you should find that the program then hangs at the while loops instead of crashing.-In Visual Studio goto "Debug"->"Attach To Process" and choose your dll or UDK editor process (this can be a bit of trail and error :S ).You can then change the wait to false and step through the code :)This feature probably exists with other IDE's if you're not using Visual Studio.   ;  I don't have access to the Unreal sourcecode. :(But I'm gonna do some MessageBox debugging to check the sanity of my variables etc   ;Quote:Original post by MatsVedI don't have access to the Unreal sourcecode. :(But I'm gonna do some MessageBox debugging to check the sanity of my variables etcWhy would you need it? you can still debug your DLL (as I understand it you are writing a DLL that unreal loads )   ;  You don't need to actually debug this using UDK, just create a basic project that contains your loading/saving code...#include <iostream>#include <fstream>struct Save{wchar_t LevelName;floatX, Y, Z;};template <typename Stream>Stream& operator << (Stream& stream, const Save& save){stream << save.LevelName;stream << save.X;stream << save.Y;stream << save.Z;return stream;}template <typename Stream>Stream& operator >> (Stream& stream, Save& save){stream >> save.LevelName;stream >> save.X;stream >> save.Y;stream >> save.Z;return stream;}int main(int argc, char* argv[]){{Save test;test.X = 2.0f;test.Y = 4.0f;test.Z = 8.0f;test.LevelName = L'T';std::wofstream os("test.txt");os << test;}{Save test;std::wifstream is("test.txt");is >> test;}return 0;}If you take a look at the contents of test.txt that should give you some clue as to why this is not working:T248How should operator >> intepret this data into a wide char and three floats? You need some way to distinguish which part of the text belongs to which field, for example you could put each field on a seperate line, or use some other token to delimit the fields:T248template <typename Stream>Stream& operator << (Stream& stream, const Save& save){stream << save.LevelName << '\n';stream << save.X << '\n';stream << save.Y << '\n';stream << save.Z << '\n';return stream;}template <typename Stream>Stream& operator >> (Stream& stream, Save& save){std::wstring str;std::getline(stream, str);save.LevelName = boost::lexical_cast<wchar_t>(str);std::getline(stream, str);save.X = boost::lexical_cast<float>(str);std::getline(stream, str);save.Y = boost::lexical_cast<float>(str);std::getline(stream, str);save.Z = boost::lexical_cast<float>(str);return stream;}Although if you are willing to use boost there is a great serialisation library included which will handle this for you easily, as well as providing different archive types.   ;  I actually did this earlier:__declspec(dllexport) unsigned int SaveGame(wchar_t* LevelName, float X, float Y, float Z, wchar_t* SavePath){wofstream SaveStream(SavePath, ios::out);SaveStream << LevelName;SaveStream << std::endl;SaveStream << X;SaveStream << std::endl;SaveStream << Y;SaveStream << std::endl;SaveStream << Z;SaveStream << std::endl;SaveStream.close();return 1;}But it didn't seem to have any effect, so I removed it. Is there any standard equivalent to boost:lexical_cast?   ;Quote:Original post by MatsVedI actually did this earlier:*** Source Snippet Removed ***But it didn't seem to have any effect, so I removed it. It may well be that the crash is caused by something else, but your load/save code is definately broken without some delimeter between the fields.  I imagine that one or more of those variables will remain uninitialised.  Do you have any more information about the crash?Quote:Is there any standard equivalent to boost:lexical_cast?I believe it is part of tr2 although you can simulate the effect quite simply (I'm pretty sure the boost::lexical_cast does some other trickery, including error conditions and such):template <typename Target, typename Source>Target lexical_cast(Source source){Target target;std::ostringstream os;os << source;std::istringstream is(os.str());is >> target;return target;};  Ok, so I got the thing to work in UDK (turns out I was doing something wrong with the UnrealScript code).But I still have a problem... no text is actually read from the file and into the struct I'm returning. :I created a test program for myself, and a ReadLine function.// LoadTest.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <fstream>#include <iostream>#include <sstream>#include "OSFDlg.h"#include <assert.h>using namespace std;template <typename Target, typename Source>Target lexical_cast(Source source){Target target;std::ostringstream os;os << source;std::istringstream is(os.str());is >> target;return target;}struct Save{wchar_t *LevelName;float X, Y, Z;};wchar_t LoadDiag(){//FilterTCHAR szFilter[] = TEXT("Save Files (*.SAV)\0*.sav\0");//Default ExtensionTCHAR szDefExtension[] = TEXT("sav\0");COSFDialog LoadDiag;if(LoadDiag.FileOpenDlg(szFilter, szDefExtension, TEXT("Load Game"), false))return (wchar_t)LoadDiag.GetFileName();}wchar_t* ReadLine(wifstream *Stream){wchar_t *Line = new wchar_t[256];wchar_t ControlChar = '0';int i = 0;while(ControlChar != '\n'){ControlChar = Stream->get();Line = ControlChar;i++;if(i == 256)break;}return Line;}__declspec(dllexport) Save* LoadGame(wchar_t* LoadPath){wifstream LoadStream(LoadPath, ios::in);wchar_t X;wchar_t Y;wchar_t Z;static Save NewSave;NewSave.LevelName = new wchar_t[100];NewSave.LevelName = ReadLine(&LoadStream);LoadStream >> X;NewSave.X = lexical_cast<float, wchar_t>(X);LoadStream >> Y;NewSave.Y = lexical_cast<float, wchar_t>(Y);LoadStream >> Z;NewSave.Z = lexical_cast<float, wchar_t>(Z);/*LoadStream >> NewSave.X;LoadStream >> NewSave.Y;LoadStream >> NewSave.Z;*/LoadStream.close();MessageBox(NULL, (LPCWSTR)*NewSave.LevelName, TEXT("LoadGame()"), MB_OKCANCEL);return &NewSave;}int _tmain(int argc, _TCHAR* argv[]){wchar_t SavePath = LoadDiag();Save *Sav = LoadGame(&SavePath);assert(Sav);return 0;}When the MessageBox is displayed, it is empty! This makes me assume that no text is being read. So what is the problem here?   ;  I see, you are doing something wrong with that wchar_t in your MessageBox:This:MessageBox(NULL, (LPCWSTR)*NewSave.LevelName, TEXT("LoadGame()"), MB_OKCANCEL);should become this:MessageBox(NULL, (LPCWSTR)NewSave.LevelName, TEXT("LoadGame()"), MB_OKCANCEL);NewSave.LevelName is a *wchar_t type. And the message box takes a LPCWSTR which is not more than an const wchar_t*.Also, you don't delete the memory you allocate after use, or do you?Anyways, this would be better:struct Save{wchar_t LevelName[100];float X, Y, Z;};So you don't need to allocate new memory. But note that you have to cast that string to a LPWSTR or an LPCWSTR when you want to use it!(LPWSTR)&LevelName should do that.;  Hm.I changed it to:MessageBox(NULL, (LPCWSTR)NewSave.LevelName, TEXT("LoadGame()"), MB_OKCANCEL);The messagebox is still empty. I'm worried that no data is getting read. How do I fix this? :\   