While constructing a plugin that utilizes a linked static library, I’ve run into a recurring access violation upon running the following test function. What confuses me is that the issue is rather specific to a handful of pointers within a struct defined in the static library. Testing the library externally with the same version of MSVC yields no issues:
From AnvilGen.cpp (my plugin):
#include "mcmap.h"
void UAnvilGen::TestMessage()
{
if (IAnvilGenPlugin::isAvailable())
{
const char* AnvilPath = "..\\..\\..\\..\\..\\Anvil\\TestWorld\\";
struct mcmap_region *Region = mcmap_region_read(0, 0, AnvilPath); // WORKS FINE
struct mcmap_region_chunk *NewChunk = &Region->chunks[0][0]; // ALSO WORKS
// ERROR ON THIS LINE
struct mcmap_chunk *Chunk = mcmap_chunk_read(NewChunk, MCMAP_PARTIAL, 0);
}
}
After calling TestMessage() on game start in a blueprint, the stack trace points to the line indicated above. More specifically, it directs me to the following pointer:
From mcmap.c (compiled in the static library):
struct mcmap_chunk *mcmap_chunk_read(struct mcmap_region_chunk *rc, mcmap_mode m, int rem)
{
nbt_compression_type type;
struct mcmap_chunk *c;
struct nbt_tag *t, *p, *l;
int8_t y_index;
unsigned int x,y,z, i;
//don't index into NULL struct
if (rc == NULL || rc->header == NULL) // <---- ERROR HERE @ rc->header
return NULL;
// ...continued
Before the above, rc->header was initialized like so:
//connect pointers
if (r->locations[z][x] >= 2)
{
//connect 5-byte chunk header
r->chunks[z][x].header = (struct mcmap_region_chunk_header *)&(b[i]);
//'r->chunks[z][x].data' will now point to a block of 'r->chunks[z][x].size' bytes
r->chunks[z][x].data = &(b[i+5]);
}
return;
}
What confuses me is that no other application throws an error with any of the functions in the static library, not even with the same version of MSVC used on UE4. This should be a fairly straightforward null check, but UE4 crashes each time an operation checks or uses said pointer.
From mcmap.h (in the include directory):
struct mcmap_region_chunk_header //5-byte metadata for each chunk
{
uint8_t length[4];
uint8_t compression;
}; // PACKED; <--- Was originally packed, doesn't work in either case.
struct mcmap_region_chunk
{
struct mcmap_region_chunk_header *header;
size_t size;
uint8_t *data;
};
Not sure if there is some convention of UE4 that I am missing, though I can’t see where this pointer could be going wrong; especially given that it is handled primarily outside the scope of the engine. I am using version 4.6.1 of the engine (binary).