Get current ISO datetime string using boost - date

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.

Related

Arduino - Uploading sketch in vs code failed, But Arduino IDE OK

#include <DS3231.h>
DS3231 rtc(SDA, SCL);
void setup()
{
Serial.begin(9600);
rtc.begin();
Serial.println("Setup...");
}
void loop()
{
Serial.println("Loop...");
// // Send time
Serial.println(rtc.getTimeStr());
delay(2000);
}
This is simple code. Uploading this skecth in Arduino IDE works well, I can see the serial logs
Setup...
Loop...
12:18:01
Loop...
12:18:03
Loop...
12:18:05
With No problem.
But when I upload this code in VS Code, It wouldn't work.
The output below
[Starting] Uploading sketch 'smartfarm.ino'
Please see the build logs in output path: c:\Projects\ArduinoOutput
설정파일 로딩... // loading configuration...
패키지 초기화... // initializing packages...
보드 준비... // ready to board...
확인... // ok...
C:\Users\appton-2\Documents\Arduino\libraries\DS3231/DS3231.h:77:7: warning: type 'struct DS3231' violates the C++ One Definition Rule [-Wodr]
class DS3231
^
C:\Users\appton-2\Documents\Arduino\libraries\DS3231\DS3231.h:62:7: note: a different type is defined in another translation unit
^
C:\Users\appton-2\Documents\Arduino\libraries\DS3231/DS3231.h:100:11: note: the first difference of corresponding definitions is field '_scl_pin'
uint8_t _scl_pin;
^
C:\Users\appton-2\Documents\Arduino\libraries\DS3231\DS3231.h:69:13: note: a field with different name is defined in another translation unit
uint8_t date;
^
C:\Users\appton-2\AppData\Local\Temp\ccp574Yq.ltrans0.ltrans.o: In function `global constructors keyed to 65535_0_smartfarm.ino.cpp.o.1845':
<artificial>:(.text.startup+0x60): undefined reference to `DS3231::DS3231(unsigned char, unsigned char)'
C:\Users\appton-2\AppData\Local\Temp\ccp574Yq.ltrans0.ltrans.o: In function `setup':
c:\Projects\smartfarm/smartfarm.ino:9: undefined reference to `DS3231::begin()'
C:\Users\appton-2\AppData\Local\Temp\ccp574Yq.ltrans0.ltrans.o: In function `loop':
c:\Projects\smartfarm/smartfarm.ino:16: undefined reference to `DS3231::getTimeStr(unsigned char)'
collect2.exe: error: ld returned 1 exit status
exit status 1
IntelliSense configuration already up to date. To manually rebuild your IntelliSense configuration run "Ctrl+Alt+I"
[Error] Uploading sketch 'smartfarm.ino': Exit with code=1
Do you know the reason? Am I missing something? I changed DS3231 lib to another lib.
Now it works well. The reason was I guess "Output Path" in vs code arduino. vs code ask me to input outputPath for fast building before. Perhaps the previous library remained here even if I changed to new one. I removed all files in outputPath now it works fine :) –

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)

Can't process quickfix messages written in file

In my C++ QuickFix application, I am recording all MarketDataIncrementalRefresh messages i am getting into a file. This is being done using the following code:
void Application::onMessage(const FIX44::MarketDataIncrementalRefresh& message, const FIX::SessionID&)
{
ofstream myfile("tapedol.txt", std::ios::app);
myfile << message << endl << endl;
}
This part's working just fine. The problem occurs when I try to load the message later on.
FIX::Message msg
ifstream myfile("tapedol.txt");
getline(myfile,aux);
msg = aux;
msg.getField(55);
The program crashes every time it executes the last line. I suspect the problem is at the assignment to msg, but i'm not sure. If it is, what is the correct way to do such assignment? If not, how can I process the data within tapedol.txt, so that a message of type MarketDataIncremental refresh would be generated for each string in the file?
Your question is not complete enough to provide a full answer, but I do see one red flag:
msg.getField(55);
The Symbol field is not a top-level field of MarketDataIncrementalRefresh (it's inside the NoMDEntries repeating group), so this line will fail. I think it would raise a FieldNotFound exception.
My C++ is rusty, but you should be able to catch an exception or something that should tell you exactly what line is erroring out. Barring that, you need to open up a debugger. Just saying "it crashed" means you quit looking too soon.

on iOS/iPhone: "Too many open files": need to list open files (like lsof)

We've discovered our complex iPhone app (ObjC, C++, JavaScript/WebKit) is leaking file descriptors under unusual circumstances.
I need to know which files (by file path) we are leaving open.
I want something like the BSD command "lsof", which, of course, isn't available in iOS 4, at least not to me. Ideally a C or ObjC function. Or a tool, like shark or Instruments. Just need the files for our running app, not (as with lsof) for all apps/processes.
We do all sorts of things with files, and the code that is failing with "Too many open files" hasn't changed in ages, and since the circumstances are unusual, this could have crept in months ago. So there's no need to remind me to look at code that opens files and make sure I close them. I know that already. Would be nice to narrow it down with something lsof-esque. Thanks.
#import <sys/types.h>
#import <fcntl.h>
#import <errno.h>
#import <sys/param.h>
+(void) lsof
{
int flags;
int fd;
char buf[MAXPATHLEN+1] ;
int n = 1 ;
for (fd = 0; fd < (int) FD_SETSIZE; fd++) {
errno = 0;
flags = fcntl(fd, F_GETFD, 0);
if (flags == -1 && errno) {
if (errno != EBADF) {
return ;
}
else
continue;
}
fcntl(fd , F_GETPATH, buf ) ;
NSLog( #"File Descriptor %d number %d in use for: %s",fd,n , buf ) ;
++n ;
}
}
For future reference, I ran into a similar problem on an iPhone 11 with iOS 13; I was creating too many file descriptors (FDs) by creating too many files and sockets. My solution was to increase FDs at runtime with setrlimit().
First I got the FD limits on my iPhone 11, with the following code:
// This goes somewhere in your code
struct rlimit rlim;
if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
std::cout << "Soft limit: " << rlim.rlim_cur << std::endl;
std::cout << "Hard limit: " << rlim.rlim_max << std::endl;
} else {
std::cout << "Unable to get file descriptor limits" << std::endl;
}
After running getrlimit(), I could confirm that on iOS 13, the soft limit is 256 FDs, and the hard limit is infinite FDs. Since I was creating > 300 FDs between files and sockets, my app was crashing.
In my case I couldn't decrease the number of FDs, so I decided to increase the FD soft limit instead, with this code:
// This goes somewhere in your code
struct rlimit rlim;
rlim.rlim_cur = NEW_SOFT_LIMIT;
rlim.rlim_max = NEW_HARD_LIMIT;
if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
std::cout << "Unable to set file descriptor limits" << std::endl;
}
NOTE: You can find more information on gettrlimit() and setrlimit() here and here.
Can you reproduce the problem running in the simulator?
If so, then you could actually use "lsof"...
update:
Ok, if you can't use the simulator, then idea #2:
When you get the "too many open files" error, call a function that iterates through all open file descriptors and dumps some information about each (for example the length and the first few bytes).
Can't you just intercept all file opens with your own function, say my_fopen, and store the descriptors along with their names so that when you have too many files opened, you can go through your list to see what's taking all the descriptors?
If Instruments isn't working well for your purposes, my next recommendation would be to run your app in the simulator, and use fs_usage on the command line to track the file descriptors you're opening and closing. Something like this:
In Terminal, run "sudo fs_usage -f filesys MyAppName", replacing MyAppName with the name of your app.
Launch your app.
Look at the file descriptor open and close commands output by fs_usage to see which files you're leaving open.
Instruments.app might be able to help you (/Developer/Applications/Instruments.app). Run your app using the System Usage tool in Instruments, and it'll probably show you what you need to know. Best of all, it can be used while running the app on your device, without jailbreaking it.
I suggest you run your app on a jailbroken iPhone, and use Backgrounder and MobileTerminal to take a look at the files currently open.
You can get an iPhone binary of lsof here: http://modmyi.com/cydia/package.php?id=6945

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

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.