Error C2679 when attempting to use std::wcout << wstring-var; vc++ 2008 express - unicode

I'm getting a rather odd error message when attempting to wcout a wstring in vc++ 2008 express:
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::wstring' (or there is no acceptable conversion)
If I understand this correctly it's reporting that wcout does not accept a wstring? I ask someone to compile this code under linux and it runs fine. I also tried the same code on another computer with vc++ 2008 express and still fails. A known issue with std in vc++ 2008?
#include <iostream>
int main()
{
std::wstring unicode_test = L"Unicode var";
std::wcout << L"Unicode non-var" << std::endl;
std::wcout << unicode_test << std::endl; //<-- This line fails!
}
I'm using vc++ 2008 express sp1 with all the updates up to KB948127. I'm aware that console will need codepage changes but this isn't even compiling. Thanks.

You need to #include <string>. I'm not sure what the standard says, but I'm quite sure that <iostream> is not required to export all of <string>, if any.
[edit]At least cplusplus.com does not even list string as the types declared in <iostream>. No, it's not the standard, I know...[/edit]

For those with this problem, you may need to enable multi-byte printing in the console. See the answer here: https://stackoverflow.com/a/41584090/1599699
And my comment:
I was having trouble printing a wstring that I instantiated with a greater length than the data I was supplying due to sizeof(wchar_t) == sizeof(char) * 2, and then printing anything after that wasn't succeeding.

Related

Boost Asio tcp::iostream construction raise an Access Violation Exception on every second use

I am trying to use the implementation of std::iostream provided by boost::asio on top of boost::asio::ip::tcp::socket. My code replicate almost line to line the example that is published in Boost Asio's documentation:
#include <iostream>
#include <stdexcept>
#include <boost/asio.hpp>
int main()
{
using boost::asio::ip::tcp;
try
{
boost::asio::io_service io_service;
tcp::endpoint endpoint(tcp::v4(), 8000);
tcp::acceptor acceptor(io_service, endpoint);
for (;;)
{
tcp::iostream stream; // <-- The exception is triggered on this line, on the second loop iteration.
boost::system::error_code error_code;
acceptor.accept(*stream.rdbuf(), error_code);
std::cout << stream.rdbuf() << std::flush;
}
}
catch (std::exception& exception)
{
std::cerr << exception.what() << std::endl;
}
return 0;
}
The only difference is the use I make of the resulting tcp::iostream: I forward everything I receive to the standard output.
When I compile this code with VisualStudio2019/toolset v142 and Boost from the NuGet boost-vc142, I get an Access Violation Exception only in the second iteration in the for loop, in the function
template <typename Service>
Service& service_registry::use_service(io_context& owner)
{
execution_context::service::key key;
init_key<Service>(key, 0);
factory_type factory = &service_registry::create<Service, io_context>;
return *static_cast<Service*>(do_use_service(key, factory, &owner));
} // <-- The debugger show the exception was raised on this line
in asio/detail/impl/service_registry.hpp. So the first iteration everything goes as planned, the connection is accepted, the data shows up on the standard output, and as soon as the stream is instanciated on the stack for the second time, the exception pops.
I don't have a high confidence in the accuracy of this location of the exception reported by the debugger. For some reason, the stack seams to be messed up and show only one frame.
If the declaration of stream is moved out of the loop, no exception is raised any more but then I need to stream.close() at the end of the loop, or nothing shows up on the standard output except the data from the first client's connection.
Basically, as soon as I try to instanciate more than one boost::asio::tcp::iostream (not necessarily at the same time), the exception is raised.
I tried the exact same code under linux (Arch linux, latest version of g++, same version of Boost) and everything works perfectly.
I could work around this issue by not using iostreams, but my idea is to feed the data received on the tcp socket to a parser which only accept implementations of std::iostream, hence I would still need to wrap asio's tcp socket in an homebrewed (and mediocre) implementation of std::iostream.
Does anybody have an idea on what's wrong with this setup, if I missed a crucial #define somewhere or anything?
Update:
Subsequent investigation show that the only situation where the access violation happens is when the executable is run from within Visual Studio (typ. from the menu Debug -> Start Debugging).
The build process seems to have no effect (calling directly cl.exe, using MSBuild, using devenv.exe).
Moreover, if the executable is run from a command prompt, and only then the debugger is attached, no access violation happens.
At this point, the issue is most likely not linked to the code itself.
Okay, it was exceedingly painful to test this on windows.
Of course I first tried on Linux (clang/gcc) and MingW 8.1 on windows.
Then I bit the bullet and jumped the hoops to get MSVC in command line with boost packages¹.
I cheated by manually copying the .lib/.dll for boost_{system,date_time,regex} into the working directory so the command line stayed "wieldy":
C:\work>C:\Users\sghee\Downloads\nuget.exe install boost_system-vc142
C:\work>C:\Users\sghee\Downloads\nuget.exe install boost_date_time-vc142
C:\work>C:\Users\sghee\Downloads\nuget.exe install boost_regex-vc142
(Be sure to get some coffee during those)
C:\work\> cl /EHsc test.cpp /I .\boost.1.72.0.0\lib\native\include /link
Now I can run test.exe
C:\work\> test.exe
And it listens fine, accepts connections (sequentially, not simultaneously). If you connect a second client while the first is still connected, it will be queued and be accepted only after the first disconnects. That's fine, because it's what you expect with the synchronous accept and loop.
I used Ncat.exe (from Nmap) to connect:
C:\Program Files (x86)\Nmap>.\ncat.exe localhost 8000
Quirk: The buffering was fine with the MSVC cl.exe build (linewise) as opposed to MingW behaviour, even though MingW also uses ws2_32.dll. #trivia
I know this doesn't "help", but maybe you can compare notes and see what is different with your system.
Video Of Test
¹ (that's a tough job without VS and also I - obviously - ran out of space, because 50GiB for a VM can't be enough right)

'Concurrency': a namespace with this name does not exist

I am an amateur C# programmer who strayed into C++ because of a need for the C++ AMP technology for some heavy-duty number crunching. Hence, my C++ programming skills are not very well developed.
For my first attempt at an actual program, I chose code based on a Daniel Moth's April 2012 article. I cannot get it to build. I always get the error:
C2871 ‘Concurrency’: a namespace with this name does not exist.
I know that the code was first written for Visual Studio 11, but I only had VS 2008 and VS 2010 on my machine. So, I installed VS 2017 (version 15.9.4, .Net 4.7.03062). I started with an empty C++ project but had trouble with it. The best I could do, after I worked through all the things it didn’t recognize, was an error:
C3861: ‘access’ identifier not found, line 2616 in file ‘amp.h’.
So I started again, this time with an empty Windows Console Application project. Again, I had to tweak the code considerably to migrate from Visual Studio 11 to VS 2017, but ended up with code as shown below.
I tried what I could to find the source of the error. I targeted both x64 and x86, but it made no difference. I commented out line 5 and lines 21 – 27, and the code would build and execute. IntelliSense showed no problems, either with identifiers or syntax. In fact, the mouse-over info recognized the Concurrency constructs as such. I deliberately misspelled Concurrency, but IntelliSense caught that right away. I looked through the project properties with an eye toward a setting that needed to be changed to run AMP, but as I wasn’t even sure what I was looking for, I didn’t find anything.
I tried to find the name of the file in which Concurrency is defined, so that I could search my machine to see if it was there, and to add a path if it was, but was unsuccessful. I couldn’t even find the file name. I googled and pored through on-line sources and MS Docs, but no matter how I phrased my search questions, I didn’t find any answers.
The error says:
Concurrency does not exist
which to me means it can’t find it, it’s not on the machine, or some build setting is preventing it from being used. Most of the on-line articles about writing AMP code say nothing about build settings. Does it not require anything different than a serially-coded project? Is it as simple as a missing reference? If so, where do I go to find it? With my limited experience, I don’t know what else to try.
My machine is a Win 7 SP1 box. The KB2999226 bug fix has been installed. I didn’t install all of VS 2017 since I am only interested in C# and C++. Did I fail to install something I should have?
If this problem was addressed before, I couldn’t find it. So, any help would be appreciated.
1. #include <amp.h>
2. #include "pch.h"
3. #include <iostream>
4. #include <vector>
5. using namespace Concurrency;
6.
7. int main() {
8. const int M = 1024; const int N = 1024; //row, col for vector
9. std::vector<int> vA(M*N); std::vector<int> vB(M*N); //vectors to add
10. std::vector<int> vC(M*N); //vector for result
11.
12. for (int i = 0; i < M; i++) { vA[i] = i; } //populate vectors
13. for (int j = N - 1; j >= 0; j--) { vB[j] = j; }
14.
15. for (int i = 0; i < M; i++) { //serial version of
16. for (int j = 0; j < N; j++) { //matrix addition
17. vC[i*N + j] = vA[i*N + j] + vB[i*N + j]; //using vectors
18. }
19. }
20.
21. extent<2> e(M, N); //uses AMP constructs but no
22. array_view<int, 2> a(e, vA), b(e, vB); //parallel functions invoked
23. array_view<int, 2> c(e, vC);
24. index<2> idx(0, 0);
25. for (idx[0] = 0; idx[0] < e[0]; idx[0]++) {
26. for (idx[1] = 0; idx[1] < e[1]; idx[1]++) {
27. c[idx] = a[idx] + b[idx];
28. }
29. }
30. // C2871 'Concurrency': a namespace with this name does not exist. Line 5
31. // Also C2065, C3861, C2062 for all Concurrency objects Line 21 - Line 27
32. }
33.
With,
#include "amp.h"
#include "pch.h"
#include <iostream>
using namespace concurrency;
I get,
C2871 'concurrency': a namespace with this name does not exist
However, with,
#include "pch.h"
#include <iostream>
#include "amp.h"
using namespace concurrency;
there is no error.
I suggest moving #include "amp.h" as shown.
I also used both concurrency and Concurrency. There was no difference.
For the error C3861: ‘access’ identifier not found, line 2616 in file ‘amp.h’.
From the menu, select Project, then select Properties.
In the Property Pages window, under C/C++, select All Options, then select Conformance mode.
Change Yes (/permissive-) to No. Select OK.
Build the project and run.
By default, the /permissive- option is set in new projects created by Visual Studio 2017 version 15.5 and later versions. It is not set by default in earlier versions. When the option is set, the compiler generates diagnostic errors or warnings when non-standard language constructs are detected in your code, including some common bugs in pre-C++11 code.
More information may be found here.
This suggests, to me, that "amp.h" is not conforming to the changes made to C++ 15.5. Thus it worked with C++ in VS 2015 14.0 (Update 3), then failed with C++ in VS 2017 15.9.5.

Get current ISO datetime string using boost

Just trying to log timestamps to an output file like so:
//#include <boost/date_time.hpp>
boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
std::cout << boost::posix_time::to_iso_extended_string(now) << std::endl;
// ideally one line
std::cout << boost::posix_time::to_iso_extended_string(
boost::posix_time::second_clock::local_time()) << std::endl;
Getting errors in boost:
boost::date_time::month_formatter<boost::gregorian::greg_month, boost::date_time::iso_extended_format<char>, char>::format_month(boost::gregorian::greg_month const&, std::ostream&)':
/usr/include/boost/date_time/date_formatting.hpp:44: undefined reference toboost::gregorian::greg_month::as_short_string() const'
/usr/include/boost/date_time/date_formatting.hpp:49: undefined reference to `boost::gregorian::greg_month::as_long_string() const'
I know this is probably a problem my end not boost but not sure how to debug, any ideas?
You need to link the appropriate library. Depending on your build system that might mean adding something like -lboost_date_time to your link or final build command.
Whenever you see "undefined reference" it means your code compiled just fine, but you have a library missing in your build.

Linux DD passing data to serial port ttyS0

Hi i want to pass a data from my char device driver to serial port ttyS0..
I have created a simple char driver module which reads and write and it's my first tym doing it.. i am using debian guest os...
e.g.
echo "hello" > /dev/mydev
now when /dev/mydev receives the data it will then alter the string into something like "hello too" which is passed to my serial port /dev/ttyS0..
how can i alter the string?.. is it possible to use if statement inside mydev?
e.g
if(string=="hello"){
alterstringTO: hello to;
pass "hello to" /dev/ttyS0;
like echoing in terminal..
echo "hello to" > /dev/ttyS0
}
Is that possible?... or is there any other way doing it?
Here some of the code..
ssize_t dev_read(struct file *filp, char *buf, size_t clen, loff_t *f_pos){
short cnt =0;
while(clen && (msg[Pos]!=0))
{
put_user(msg[Pos],buf++);
cnt++;
clen--;
Pos++;
}
return cnt;
}
ssize_t dev_write(struct file *filp, const char *buf, size_t clen, loff_t *f_pos){
short dec = clen-1;
short cnt=0;
memset(msg,0,50);
Pos=0;
while(clen>0)
{
msg[cnt++] = buf[dec--];
clen--;
}
return cnt;
}
Thanks in advance..
Just a comment on writing to the serial port:
Remember the Linux foundations, everything is a file in Linux. To write to the device driver from a program you need to open the file for writing and then you can fprintf whatever data you want. You can do that from user space as well (the recommended way)
Refer to the following man pages:
man fopen
man fread/fwrite
man fprintf
man fclose
I'm not exactly sure what you are trying to achieve here, as the question and the intent seems unclear to me. I'll provide some guidance, but recommend that you edit your question and make it more readable.
Your snippet to compare strings is not correct. You can learn more about how to compare strings in C in here.
Altering a string in C is a basic operation that you learn when you start working with strings. This should help you getting started.
As final remark, please note that programming for the kernel requires extra care. A small mistake may lead to a crash and loss of data. If you really must, then the book Linux Device Drivers 3rd Edition is freely available and can help you further.

Send data from Visual C++ via socket on the same machine

I am currently in a project involving data visualization of a signal captured from a device which has a Visual C++ API. I currently can log each datasample to file, but I'd like to do some sort of plot to screen.
I have had a previous successful experience with a similar job using socket between C++ and Python, but the code was lost. I have the Python socket "receiver" to reuse, but don't have the Visual C++ "sender" to reverse engineer or otherwise copy/paste.
My current Python code, which was working very fine, is:
import SocketServer
class SocketHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request[0].strip()
## do something with 'data' here!
server = SocketServer.UDPServer(("192.168.1.23", 8888), SocketHandler)
server.serve_forever()
And the part of the Visual C++ that currently logs to file and I want to send to the socket is:
#include <fstream>
//(...lots of code...)
short int * dataBuff;
unsigned int dataNum;
int isAcqRunning;
int startFromTrg, stopFromTrg;
unsigned int firstSample, lastSample;
int errcode;
int i;
std::ofstream out("./out.txt");
// device->transferData is called inside a loop
// to get data from aquisition hardware's buffer
errcode = device->transferData(&dataBuff, &dataNum, &isAcqRunning,
&startFromTrg, &stopFromTrg,
&firstSample, &lastSample);
if(errcode == 0)
{
printf("\n Acquired samples: %d", dataNum);
for (i=firstSample; i<lastSample; i++)
out<<dataBuff[i]<<'\n'; /////// I'd like to send dataBuff[i] via socket!!
}
//(...lots of more code...)
Possibly useful additional information:
I'm using VisualStudio 2010 in Windows7;
This is the first time I touch C++ code in my life, I use Python almost exclusively;
I haven't have success trying to follow C++ examples from books and sites because, as it appears, C++ and VISUAL C++ are NOT the same thing and can behave very differently :o(
I thank very much for any help, and for reading this.
(EDIT: if there is a better way to do that without any additional complexity overhead for a noob, I would be glad to try. I like the socket stuff because it is language-transparent and solved a previous problem with very good speed)