Strange stack variable corruption error after calling extern(C) function

cc via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue May 3 04:32:31 PDT 2016


Hello, I've been encountering a strange problem that seems to 
occur after calling some external C functions.  I've been working 
on a program that incorporates the FMOD C API for playing sound, 
with a simple D binding based off the C headers, and actually 
everything works more or less fine, I've had working sound in my 
program for a few months now.  However I recently started 
noticing some strange behavior, currently using DMD v2.070.2 
(haven't tried v2.071 yet, will soon).  I can't post the entire 
program but I'll include the relevant code, I might try to make a 
small working compilable sample if this isn't enough information.


// fmod/c/fmod.d:
// Adapted from C headers
extern(C):
struct FMOD_SYSTEM;
struct FMOD_SOUND;
enum FMOD_RESULT : int { ... }
enum FMOD_MODE : uint { ... }
FMOD_RESULT FMOD_System_CreateSound(FMOD_SYSTEM *system, const 
char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO 
*exinfo, FMOD_SOUND **sound);

// sound.d:
class Sound {
	static immutable string pathPrefix = "data/sound/";
	enum FMOD_MODE mode = FMOD_MODE.FMOD_LOOP_OFF | 
FMOD_MODE.FMOD_3D | FMOD_MODE.FMOD_3D_HEADRELATIVE | 
FMOD_MODE.FMOD_3D_LINEARSQUAREROLLOFF;

	FMOD_SOUND *snd;
	FMOD_CHANNEL *channel;
	string name;

	void load() {
		string fullpath = pathPrefix ~ name ~ ".wav";

		writefln("loading sound before: <%s> <%s> [%08x] <%s>", 
pathPrefix, name, fullpath.ptr, fullpath);
		FMOD_System_CreateSound(system, fullpath.toStringz, mode, null, 
&snd);
		writefln("A loading sound after: <%s> <%s> [%08x] <%s>", 
pathPrefix, name, fullpath.ptr, fullpath);
		writefln("B loading sound after: <%s> <%s> [%08x] <%s>", 
pathPrefix, name, fullpath.ptr, fullpath);
		if (1) {
			writefln("C loading sound after: <%s> <%s> [%08x] <%s>", 
pathPrefix, name, fullpath.ptr, fullpath);
		}
	}
}

// Output:
loading sound before: <data/sound/> <slash0> [04368a40] 
<data/sound/slash0.wav>
A loading sound after: <data/sound/> <slash0> [04368a40] 
<data/sound/slash0.wav>
B loading sound after: <data/sound/> <slash0> [04368a40] 
<data/sound/slash0.wav>
C loading sound after: <data/sound/> <slash0> [005df255] <C 
loading sound after: <%s> <%s> [%08x] <%s>>


As you can see I concatenate the path, filename, and extension 
strings, simple enough, then pass the result of .toStringz to the 
function.  What happens next is the bizarre behavior to the 
fullstring variable: Everything is fine until the program enters 
the if check, then for some reason the value of fullpath changes 
to be that of the string literal being passed to writefln().  If 
I try to do something else such as save the value of fullpath as 
a class member variable first, I get some other problem like 
object.Error@(0): Access Violation when it comes time to print 
the string.  The sound itself still plays fine, but something is 
getting corrupted by something, somewhere, and I'm completely at 
a loss as to understand what's going on.  Does anyone have any 
advice on what's happening here?


More information about the Digitalmars-d-learn mailing list