Solved

Cannot access cout from inside a dll

Posted on 2004-04-27
12
685 Views
Last Modified: 2013-12-14
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
Comment
Question by:platinumdragon
  • 6
  • 4
12 Comments
 
LVL 6

Expert Comment

by:Mafalda
ID: 10937650
1. Does it work on an executable ?
2. Maybe the problem is the mixing of Managed C++ and non Managed C++ code.
0
 
LVL 6

Expert Comment

by:Mafalda
ID: 10937808
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
 

Author Comment

by:platinumdragon
ID: 10941029
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
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

Author Comment

by:platinumdragon
ID: 10941044
Oh, and yes, it works when printing to cout before accessing the dll.  It's just the call from within the dll.
0
 
LVL 6

Expert Comment

by:Mafalda
ID: 10941630
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
 

Author Comment

by:platinumdragon
ID: 10941714
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
 

Author Comment

by:platinumdragon
ID: 10951256
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
 
LVL 6

Expert Comment

by:Mafalda
ID: 10953076
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
 

Author Comment

by:platinumdragon
ID: 10953434
Visual C++ Projects >> .NET >> Class Library
0
 

Author Comment

by:platinumdragon
ID: 11069795
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
 
LVL 5

Accepted Solution

by:
Netminder earned 0 total points
ID: 11293881
PAQed, with points refunded (250)

Netminder
EE Admin
0

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Add values of each row in an array 3 57
How can i compile this github project?? 2 84
Issues with C++ Class 19 92
Precision Problem in C++ 7 32
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question