Problem with char* and convering to WCHAR

I'm using VS .NET 2005 and for some reason the variable filename which is a char* is getting populated with Garbage and the variable wideFilename is not being being found???  filename is being passed into the function as a parameter like so:
     Sound( "./Assets/Sound.wav" );  //filename=./Assets/Sound.wav

then it is used by the code below
      WCHAR *wideFilename = new WCHAR[strlen( filename ) + 1];
      MultiByteToWideChar( CP_ACP, 0, filename, -1, wideFilename, strlen( filename ) + 1 );
      wideFilename[strlen( filename )] = 0;

I'm hoping someone might know why this isn't working correctly.  THanks,
ptrennumAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
Actually, ypur code seems to be OK and produces the correct results when run, e.g.

#include <windows.h>
#include <string.h>
#include <iostream>

using namespace std;

void main () {

char* filename = "./Assets/Sound.wav";

      WCHAR *wideFilename = new WCHAR[strlen( filename ) + 1];
      MultiByteToWideChar( CP_ACP, 0, filename, -1, wideFilename, strlen( filename ) + 1 );
      //wideFilename[strlen( filename )] = 0; <--- not necessary

wcout << wideFilename << endl;

delete [] wideFilename;
}

Probably you are misinterpreting what you see in the debugger.
0
ptrennumAuthor Commented:
what i'm doing is trying to load a sound.  Here is the whole function in case it helps.  it's the call to LoadObjectFromFile that is failing.  I get this error 'Access violation reading location 0xbaadf015.'  

m_sound = new Sound( "./Assets/Sound.wav" );

Sound( char *filename )
{
WCHAR *wideFilename = new WCHAR[strlen( filename ) + 1];
      MultiByteToWideChar( CP_ACP, 0, filename, -1, wideFilename, strlen( filename ) + 1 );
      //wideFilename[strlen( filename )] = 0;

      g_engine->GetSoundSystem()->GetLoader()->LoadObjectFromFile( CLSID_DirectMusicSegment, IID_IDirectMusicSegment8, wideFilename, (void**)&m_segment );
      
SAFE_DELETE_ARRAY( wideFilename );

      m_segment->Download( g_engine->GetSoundSystem()->GetPerformance() );
}
0
ptrennumAuthor Commented:
the value I'm getting for filename using the quickwatch window when I'm inside the function body is '‰' which obviosuly it isn't supposed to be.
0
Learn Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

itsmeandnobodyelseCommented:
if Sound is a class and Sound(char* filename) is the  constructor then I don't understand yor last code:

m_sound = new Sound( "./Assets/Sound.wav" );

Sound( char *filename )
{
  ...

would not compile in a cpp. It should be

Sound::Sound( char *filename )
{
    ...

}

void Sound::anotherMemberFunction()
{
    m_sound = new Sound( "./Assets/Sound.wav" );
    ...
}

Or did you extract the Sound constructor from it's class definition?

Regads, Alex
0
jkrCommented:
I'd try to move

SAFE_DELETE_ARRAY( wideFilename );

to the end of the function, i.e.

Sound( char *filename )
{
WCHAR *wideFilename = new WCHAR[strlen( filename ) + 1];
      MultiByteToWideChar( CP_ACP, 0, filename, -1, wideFilename, strlen( filename ) + 1 );
      //wideFilename[strlen( filename )] = 0;

      g_engine->GetSoundSystem()->GetLoader()->LoadObjectFromFile( CLSID_DirectMusicSegment, IID_IDirectMusicSegment8, wideFilename, (void**)&m_segment );
     
      m_segment->Download( g_engine->GetSoundSystem()->GetPerformance() );

  SAFE_DELETE_ARRAY( wideFilename );

}

Maybe 'Download()' sill accesses the original string parameter which is not duplicated.
0
ptrennumAuthor Commented:
sorry for the confusion I will post everything in hopes it will better explain.

//the creation of the sound from a seperate .cpp
m_sound = new WAGSound( "Sound.wav" );

//the sound constructor from sound.cpp
WAGSound::WAGSound( char *filename )
{
      WCHAR *wideFilename = new WCHAR[strlen( filename ) + 1];
      MultiByteToWideChar( CP_ACP, 0, filename, -1, wideFilename, strlen( filename ) + 1 );
      //wideFilename[strlen( filename )] = 0;

      // Load the sound file, then destroy the file name.
      g_engine->GetSoundSystem()->GetLoader()->LoadObjectFromFile( CLSID_DirectMusicSegment, IID_IDirectMusicSegment8, wideFilename, (void**)&m_segment );
      SAFE_DELETE_ARRAY( wideFilename );

      // Download the segment's data to the perfromance.
      m_segment->Download( g_engine->GetSoundSystem()->GetPerformance() );
}
0
itsmeandnobodyelseCommented:
>>>> the value I'm getting for filename using the quickwatch window
Try a rebuild. It looks like a build failure, e. g. cause of precompiled headers.

0
ptrennumAuthor Commented:
I tried a clean and rebuild, I also moved the safe delete down to bottom.  Still nothing.  When I hover over the wideFilename with my mouse in debug I get no intelli sense and if I try to quick watch it I get this:
            wideFilename      CXX0017: Error: symbol "wideFilename" not found      
0
itsmeandnobodyelseCommented:
Set a break point to the first statement of the constructor. Move the mouse to the filename argument after breaking in the debugger and check the tool-tip  If it is still garbage you should check the call stack window. I would assume the constructor was called from somewhere else, e. g. from a static construction. Do you have a default for the char argument in the class header?

class WGASound
{
  public:
   WGASound(char* filename = "anyfile");
};

If so, remove the default. It makes not much sense. Also change your argument to a const char* what is more usual.

Regads, Alex
0
jkrCommented:
What Version of VC++ is that? For verification purposes, you could

WAGSound::WAGSound( char *filename )
{
      MessageBoxA(NULL,filename,"ANSI Filename",MB_OK);
      WCHAR *wideFilename = new WCHAR[strlen( filename ) + 1];
      MultiByteToWideChar( CP_ACP, 0, filename, -1, wideFilename, strlen( filename ) + 1 );
      //wideFilename[strlen( filename )] = 0;

      MessageBoxW(NULL,wideFilename,"UNICODE Filename",MB_OK);
      // Load the sound file, then destroy the file name.
      g_engine->GetSoundSystem()->GetLoader()->LoadObjectFromFile( CLSID_DirectMusicSegment, IID_IDirectMusicSegment8, wideFilename, (void**)&m_segment );

      // Download the segment's data to the perfromance.
      m_segment->Download( g_engine->GetSoundSystem()->GetPerformance() );
      SAFE_DELETE_ARRAY( wideFilename );

}
0
itsmeandnobodyelseCommented:
>>>> when I hover mouse in debug I get no intelli sense
Ah. I got an idea? Do you have a class member named "filename". Or a baseclass has? Then the debugger can not decide which to show and shows nothing. And indeed you must change that.
0
ptrennumAuthor Commented:
I don't have a class member called filename
I used the message boxes and the value appears correct! However I am still getting a fail on the call to g_engine->GetSoundSystem()->GetLoader()->LoadObjectFromFile( CLSID_DirectMusicSegment, IID_IDirectMusicSegment8, wideFilename, (void**)&m_segment );

the error the compiler returns is:Unhandled exception at 0x004026d8 in TestWAGEngine.exe: 0xC0000005: Access violation reading location 0xbaadf015.

I'm using VS.NET 2005
0
ptrennumAuthor Commented:
the class header looks like this
class WAGSound
{
public:
      WAGSound( char *filename );
      virtual ~WAGSound();

      void Play( bool loop = false, unsigned long flags = DMUS_SEGF_AUTOTRANSITION );

      IDirectMusicSegment8 *GetSegment();

private:
      IDirectMusicSegment8 *m_segment; // DirectMusic segment for the sound.
};
0
jkrCommented:
Have you tried to display the names as above?
0
ptrennumAuthor Commented:
Yes I put in the message boxes you suggested and the names come out fine.  Just like they are supposed to.
0
ptrennumAuthor Commented:
even when I use the complete path to the sound file I still get the same error.  Arrrrrrrgggg
0
jkrCommented:
Any chance that 'g_engine' is causing the trouble? How is 'm_segment' declared? If all that ca nbe ruled out, try to break down

    g_engine->GetSoundSystem()->GetLoader()->LoadObjectFromFile( CLSID_DirectMusicSegment, IID_IDirectMusicSegment8, wideFilename, (void**)&m_segment );

to

pSoundSystem = g_engine->GetSoundSystem();
pLoader = pSoundSystem->GetLoader();
pLoader->LoadObjectFromFile(...);

and check whether all the pointers involved are valid.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
itsmeandnobodyelseCommented:
Delete all breakpoints and set only one to the line

      m_sound = new WAGSound( "Sound.wav" );

Check if the argument is valid so far.

Step into the constructor. If the argument is still garbage, open the Watch 1 window in the IDE and type filename. If you still get garbage only you have to use another name for the variable cause for any reason the debugger cannot show it. You also might check if you are using a valid debug database. Search with Windows explorer whether you have a new project.pdb file. check whether there are multiple versions of that file (check all disks). If so, the debugger may have used the wrong version. You must have a new .pdb file in your project debug directory (and nowhere else).

 
0
itsmeandnobodyelseCommented:
>>>> and the names come out fine.
Then it is a debugger problem only. Did you change to const char* ?

0
ptrennumAuthor Commented:
WOOOHOOOO - there was a problem with the pointer returned from  GetSoundSystem.  It wasn't returning the correct pointer.  Thank you both so much!!!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.