I'm working on saving the victory conditions for a colony map using version 3.1 of the SDK. The victory condition shows up fine on the mission objectives page when the map is first initialized. Once the map is saved and then reloaded, checking the victory conditions screen causes Outpost 2 to crash and gives me the message below.
Unhandled exception at 0x004C68A2 in Outpost2.exe: 0xC0000005: Access violation reading location 0x6FEC3254.
Below is my test code. I pulled everything out of main.cpp and used very standard values for everything to try and isolate the problem. Not sure where the mistake is though. Willing to post the full solution somewhere if it would help someone looking at it.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "Outpost2DLL\Outpost2DLL.h"
#include "OP2Helper\OP2Helper.h"
char MapName[] = "on4_01.map";
char LevelDesc[] = "Hooville Victory Test";
char TechtreeName[] = "MULTITEK.TXT";
SDescBlock DescBlock = { Colony, 1, 12, 0 };
struct ScriptGlobal
{
Trigger VictoryTrig;
};
ScriptGlobal saveData;
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hinstDLL);
}
return TRUE;
}
int InitProc()
{
saveData.VictoryTrig = CreateCountTrigger(true, true, 0, mapEvacuationModule, mapNone, 1, cmpGreaterEqual, "NoResponseToTrigger");
CreateVictoryCondition(true, true, saveData.VictoryTrig, "Evacuate 200 colonists to the starship.");
return 1; // return 1 if OK; 0 on failure
}
void AIProc() { }
void __cdecl GetSaveRegions(struct BufferDesc &bufDesc)
{
bufDesc.bufferStart = &saveData; // Pointer to a buffer that needs to be saved
bufDesc.length = sizeof(saveData); // sizeof(buffer)
}
int StatusProc()
{
return 0; // must return 0
}
SCRIPT_API void NoResponseToTrigger() { }
The crash address is deep within string processing code, such as sprintf, vsprintf, vsnprintf. A stack trace could provide more information about what is calling the string processing code, and figure out what is being passed that is causing the problem.
Is this code example complete enough to compile and reproduce the bug?
Posting the compiled DLL, and instructions to reproduce the issue could help solve it. If Sirbomber is right about it being compiler or compiler setting specific, then the compiled code would be important here.
CodeBlocks is from what I understand just an editor. If you have MSVC installed, it might be calling the MSVC compiler. It can call other compilers though, so I don't know for sure what is going on there. The name mangling, as used by Outpost 2 in the exported symbol names, is usually compiler specific, so that would imply MSVC is being used. Mind you, MSVC is popular enough that it's name mangling may have been replicated.
You can shorten your code by using some of the macros from the SDK. You can check Outpost2DLL/RequiredExports.h for details. Macros like ExportLevelDetails(levelDesc, mapName, techTreeName, missionType, numPlayers), and ExportSaveLoadData(globalVarStructName) can cut down on a lot of boilerplate code. The function StatusProc is not actually used, so you can remove it. It was present in all the built in levels, and so got included in the SDK. We found out later it doesn't need to be there.
The DllMain method can also be omitted, as a default implementation should be provided. That also eliminates the need to include windows.h.
#include "Outpost2DLL\Outpost2DLL.h"
#include "OP2Helper\OP2Helper.h"
ExportLevelDetails("Hooville Victory Test", "on4_01.map", "MULTITEK.TXT", Colony, 1);
struct ScriptGlobal
{
Trigger VictoryTrig;
} scriptGlobal;
ExportSaveLoadData(scriptGlobal);
Export int InitProc()
{
...
}
Export void AIProc() {}
Export void NoResponseToTrigger() {}