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?

Improve company productivity with a Business Account.Sign Up

x
 
jkrConnect With a Mentor Commented:
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
 
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
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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
 
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
 
itsmeandnobodyelseConnect With a Mentor Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.