Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 778
  • Last Modified:

Cannot access cout from inside a dll

Greetings,

Hopefully, this is an easy question.  Is there a particular reason I cannot access cout from within a dll?  I get the following error whenever I even try to reference it:

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
   at std.operator<<<struct std::char_traits<char> >(basic_ostream<char,std::char_traits<char> >* _Ostr, SByte* _Val) in
 c:\program files\microsoft visual studio .net 2003\vc7\include\ostream:line 706
   at TestDll.sayHello(TestDll* ) in c:\test\testdll\testdll.cpp:line 11
   at TestDll.sayHello(TestDll* )
   at main() in c:\test\testexe\testexe.cpp:line 13

I will post the source code used if requested, but TestExe is simply instantiating the TestDll class from within the dll, and calling its sayHello() member that contains:

[code]std::cout << "Hello" << std::endl;[/code]

Thanks,
Mike

0
platinumdragon
Asked:
platinumdragon
  • 6
  • 4
1 Solution
 
MafaldaCommented:
1. Does it work on an executable ?
2. Maybe the problem is the mixing of Managed C++ and non Managed C++ code.
0
 
MafaldaCommented:
The problem seems to be in the environment/project and not the code

I presume that you included

#include <iostream>

System.NullReferenceException points to the Managed C++ objects.

Try to create a new project and choose carefully it's settings
0
 
platinumdragonAuthor Commented:
Greetings,

Yes, I am including <iostream>.

With new projects, removing the "use managed extensions" setting, and all related code, I still get an error at the same point the NullReferenceException was occurring:

Unhandled exception at 0x10001a00 (TestDll.dll) in : 0xC0000005: Access violation reading location 0x00000004.

The debugger points to the ostream file in the following function (apparently the _Ostr reference is invalid, it fails when assigning a streamsize to _Pad):

template<class _Traits> inline
      basic_ostream<char, _Traits>& __cdecl operator<<(
            basic_ostream<char, _Traits>& _Ostr,
            const char *_Val)
      {      // insert NTBS into char stream
      typedef char _Elem;
      typedef basic_ostream<_Elem, _Traits> _Myos;
      ios_base::iostate _State = ios_base::goodbit;
      streamsize _Count = (streamsize)_Traits::length(_Val);      // may overflow
      streamsize _Pad = _Ostr.width() <= 0 || _Ostr.width() <= _Count
            ? 0 : _Ostr.width() - _Count;
      const typename _Myos::sentry _Ok(_Ostr);

      if (!_Ok)
            _State |= ios_base::badbit;
      else
            {      // state okay, insert
            _TRY_IO_BEGIN
            if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left)
                  for (; 0 < _Pad; --_Pad)      // pad on left
                        if (_Traits::eq_int_type(_Traits::eof(),
                              _Ostr.rdbuf()->sputc(_Ostr.fill())))
                              {      // insertion failed, quit
                              _State |= ios_base::badbit;
                              break;
                              }

            if (_State == ios_base::goodbit
                  && _Ostr.rdbuf()->sputn(_Val, _Count) != _Count)
                  _State |= ios_base::badbit;

            if (_State == ios_base::goodbit)
                  for (; 0 < _Pad; --_Pad)      // pad on right
                        if (_Traits::eq_int_type(_Traits::eof(),
                              _Ostr.rdbuf()->sputc(_Ostr.fill())))
                              {      // insertion failed, quit
                              _State |= ios_base::badbit;
                              break;
                              }
            _Ostr.width(0);
            _CATCH_IO_(_Ostr)
            }

      _Ostr.setstate(_State);
      return (_Ostr);
      }

I am thinking that maybe this has to do with the different memory spaces for the exe and dll?  Perhaps the dll can't access the basic_ostream referenced because it's in a different memory space?  If so, how can I set it locally, or even if I can is it a good idea?

If I could attach a file, I would attach the zipped solution.  It's only 11k.  If you would be willing to email me at pooky_bunny at hotmail.com, I would send it to you.

Thanks,
Mike

0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

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.

 
platinumdragonAuthor Commented:
Oh, and yes, it works when printing to cout before accessing the dll.  It's just the call from within the dll.
0
 
MafaldaCommented:
You can try to copy _Ostr (pass it by value) instead of passing it by reference.
The reference might point to a different memory space, I am not sure.
I still do not exactly get the structure of your program.
Can you describe it ?

is it like this?

main
call cout -> works
call dll
call cout from dll -> fails

????

It will better posted here so other experts can also look at it.

0
 
platinumdragonAuthor Commented:
That won't help if it's an environment/project setting as proposed above, but I'll try anything..

The main in the exe is:

int _tmain()
{
      std::cout << "Test text" << std::endl;

      TestDll* dll = new TestDll();
      dll->sayHello();

      return 0;
}

The sole function of the dll is:

void TestDll::sayHello()
{
      std::cout << "Hello" << std::endl;
}

The output is:
Test text

..and then the exception occurs..

I'm not sure how I would copy cout.  I must admit though I understand the concepts of streams, the technical implementations of them in STL is still a bit hazy for me..

Thanks,
Mike
0
 
platinumdragonAuthor Commented:
Hmm

It's odd.  Even constructing an ostringstream in the dll fails.  The simple line:

ostringstream fmt;

produces:

Unhandled exception at 0x77f69ecd in ConsoleRunner.exe: 0xC0000005: Access violation writing location 0x00000010.

- Mike
0
 
MafaldaCommented:
How are you creating your dll ?
using a Win32 console project and then selecting it to be a DLL ?
Or creating a MFC DLL ?
I would like to have the same environment to test it out
0
 
platinumdragonAuthor Commented:
Visual C++ Projects >> .NET >> Class Library
0
 
platinumdragonAuthor Commented:
Hmm..

I seem to have solved it myself, but I'm not really sure how.  I reconstructed the executable as a Win32 command line executable instead of a .NET command line executable (for a completely unrelated reason).  Now suddenly I can access cout successfully from any of the DLLs.

Thanks,
Mike
0
 
NetminderCommented:
PAQed, with points refunded (250)

Netminder
EE Admin
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.

Join & Write a Comment

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now