SIGINT was not declared in this scope - c++11

Background
I am trying to build a sample REST api app for Rasbian running on Raspberry 3. I used cpprestsdk.
Sample contains the following header file:
#include <condition_variable>
#include <mutex>
#include <iostream>
static std::condition_variable _condition;
static std::mutex _mutex;
namespace cfx {
class InterruptHandler {
public:
static void hookSIGINT() {
signal(SIGINT, handleUserInterrupt);
}
static void handleUserInterrupt(int signal){
if (signal == SIGINT) {
std::cout << "SIGINT trapped ..." << '\n';
_condition.notify_one();
}
}
static void waitForUserInterrupt() {
std::unique_lock<std::mutex> lock { _mutex };
_condition.wait(lock);
std::cout << "user has signaled to interrup program..." << '\n';
lock.unlock();
}
};
}
Issue
When compiling on MacOS, no problem occurs.
When compiling in rasbian however, I get error: 'SIGINT' was not declared in this scope error.
It is clear that SIGINT definition - #define SIGINT 2 or similar - is not reachable when compiling on rasbian.
Question
Why I am getting this error on rasbian but not on macOS? Is it because compiler cannot locate signal.h?
I made sure that include_directories in CMakeLists.txt contains required include paths.
UPDATE
Error resolved when I manually added #include <csignal>.

You haven't included signal.h.
You're including some C++ standard library headers, and as a side effect on MacOS, these happen to include signal.h. However, that isn't specified to happen so you can't rely on it working in different implementations of those headers.
Try adding:
#include <signal.h>
at the top.

On Linux the header file to include is
#include <signal.h>
On MacOS the equivalent header file to include is
#include <csignal.h>
Depending on your OS, header files always change. They should both do the same thing though

Related

Dynamic loading libpython with pybind11

I'm trying to build some shared library with pybind11 from Mac OSX. I'm running into the error:
dyld: Symbol not found: _PyBaseObject_Type
Referenced from: /Users/xxxxx/work/test_dynamic_linking/./example
Expected in: flat namespace
in /Users/xxxxx/work/test_dynamic_linking/./example
Abort trap: 6
What I'm trying to achieve is to turn off build time linking, but dynamic loading libpython in runtime with dlopen. Note the -Wl,-undefined,dynamic_lookup flag in the cmake file. I'm doing it this way because I want to build a wheel, and linking to libpython is not a good idea AFAIU.
Below is a minimial reproducible example. I'm confused that if you call functions like Py_DecodeLocale() or Py_InitializeEx() directly from main.cpp, it works fine. But calling pybind11::initialize_interpreter() fails with the error above.
If I do
nm -gU /opt/anaconda3/envs/py38/lib/libpython3.8.dylib | grep PyBaseObject
the symbol _PyBaseObject_Type is indeed defined in the lib:
0000000000334528 D _PyBaseObject_Type
If I create a wrapper shared library which wraps the calls to pybind11 functions, and dlopen it from main.cpp, it works fine. This makes me more confused.
Cmake file:
cmake_minimum_required(VERSION 3.4)
project(example)
set (CMAKE_CXX_STANDARD 11)
set(UNDEFINED_SYMBOLS_IGNORE_FLAG "-Wl,-undefined,dynamic_lookup")
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${UNDEFINED_SYMBOLS_IGNORE_FLAG}")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " ${UNDEFINED_SYMBOLS_IGNORE_FLAG}")
include_directories(pybind11/include)
include_directories(/opt/anaconda3/envs/py38/include/python3.8)
add_library(pywrapper SHARED ${CMAKE_CURRENT_SOURCE_DIR}/wrapper.cpp)
add_executable(example main.cpp)
pyembed.hpp:
#pragma once
#include "pybind11/embed.h"
namespace py = pybind11;
void initialize_interpreter_func();
struct pybind_wrap_api {
decltype(&initialize_interpreter_func) initialize_interpreter;
};
wrapper.cpp:
#include "pyembed.hpp"
#include <set>
#include <vector>
#include <iostream>
#include "pybind11/embed.h"
#include "pybind11/stl.h"
namespace py = pybind11;
void initialize_interpreter_func() {
pybind11::initialize_interpreter();
}
pybind_wrap_api init_pybind_wrap_api() noexcept {
return {
&initialize_interpreter_func,
};
}
__attribute__((visibility("default"))) pybind_wrap_api pybind_wrapper_api =
init_pybind_wrap_api();
main.cpp:
#include <pybind11/embed.h> // everything needed for embedding
#include "pyembed.hpp"
#include <stdlib.h>
#include <dlfcn.h>
#include <iostream>
#include <string>
namespace py = pybind11;
static void* pylib_handle = nullptr;
static void* pybind_wrapper_handle = nullptr;
pybind_wrap_api* wrappers = nullptr;
int main() {
std::string path_libpython = "/opt/anaconda3/envs/py38/lib/libpython3.8.dylib";
pylib_handle = dlopen(path_libpython.c_str(), RTLD_NOW | RTLD_GLOBAL);
if(!pylib_handle) {
std::cout << "load libpython failed..." << std::endl;
} else {
std::cout << "load libpython succeeded..." << std::endl;
}
std::string path_wrapper = "./libpywrapper.dylib";
pybind_wrapper_handle = dlopen(path_wrapper.c_str(), RTLD_NOW | RTLD_GLOBAL);
wrappers = static_cast<pybind_wrap_api*>(dlsym(pybind_wrapper_handle, "pybind_wrapper_api"));
std::string pythonhome = "/opt/anaconda3/envs/py38";
setenv("PYTHONHOME", pythonhome.c_str(), 1);
std::string pythonpath = "/opt/anaconda3/envs/py38/lib/python3.8/site-packages";
setenv("PYTHONPATH", pythonpath.c_str(), true);
// this line will cause it to fail with the symbol not found error
py::initialize_interpreter();
// if comment out the previous line and do the following line, it works fine. I'm confused why is so.
//wrappers->initialize_interpreter();
return 0;
}
Then do
cmake . && make && ./example

Linking gRPC on Windows for VisualC++

I am trying to use gRPC in a Visual C++ project.
So far I have:
1) Build gRPC with vcpkg: vcpkg install grpc:x64-windows
2) Integrated the vcpgk libraries with visual studio: vcpkg integrate install
So far, so good - intellisense autocompletes the namespace etc.
My client cpp file looks like this:
#include "pch.h"
#include <iostream>
#include <memory>
#include <string>
#include <grpcpp\grpcpp.h>
#include "GRPCServerInterface.grpc.pb.h"
#include "FileFormat.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using namespace GRPCServerInterface;
int main()
{
std::cout << "Hello World!\n";
// prepare send message & payload
IsFormatSupportedInput msg;
msg.set_fileextension(".asp");
// prepare reply
IsFormatSupportedOutput rpl;
// connect
FileHandler::Stub ClientStub = FileHandler::Stub(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
ClientContext context;
// execute rpc
Status status = ClientStub.IsFormatSupported(&context, msg, &rpl);
// handle result
if (status.ok())
{
std::cout << "Format supported says:" << std::endl << "\t formats read: " << rpl.readsupportedformats() << std::endl << "\t formats write: " << rpl.writesupportedformats() << std::endl;
}
else
{
std::cout << status.error_code() << ": " << status.error_message() << std::endl;
}
}
All messages & proto files exits and work in general, since I already use them in python and c# projects.
When building, Visual Studio generates a boatload of 125 errors, all in files I never touched.
In GRPCServerInterface.pb.h, there is identifier GOOGLE_DCHECK is undefined
All other errors are member abc may not be initialized in various header files in the grpc includes, for example
member "google::protobuf::Any::kIndexInFileMessages" may not be initialized in file any.pb.h. Many more in type.pb.h and descriptor.pbp.h.
Last but not least, I get prompted add #iclude "pch.h" to the auto-generated protobuf classes grpcserverinterface.grpc.pb.cc and grpcserverinterface.pb.cc - adding it changes a bit, but basically all errors are still undefined symbol and member may not be initialized. And I really do not want to modify auto-generated code every time.
What am I missing? Or is it just a fruitless endeavor to try using grpc with Visual Studio and should I just move to a build framework like bazel?
Solved it!
Two steps for solving:
1) I disabled precompiled headers for the whole project - this made the #include "pch.h go away. You could probalby get away with disabling it just for the protobuf files, as it can be done on a per-file basis.
2) One of the last errors listed was unresolved external symbol __imp_WSASocketA, which finally led me to this question Unresolved external symbol LNK2019. I just included #pragma comment(lib, "Ws2_32.lib") in one source file, and now everything works just perfect.

libxl library use in c++

When I create a project visual studio 2015 I can work this libxl library hovewer I could not be able to work that library on visual studio qt gui application project.
I try everything whatever I know.
#include "stdafx.h"
#include "QtGuiApplication5.h"
#include <QtWidgets/QApplication>
#include <qapplication.h>
#include <qpushbutton.h>
#include <iostream>
#include <conio.h>
#include "libxl.h"
using namespacenclude <Qt libxl;
using namespace std;
int main(int argc, char *argv[])
{
Book* book = xlCreateBook();
if (book)
{
if (book->load(L"..\\Lab_Bus Datebase.xlsx"))
{
Sheet* sheet = book->getSheet(0);
if (sheet)
{
const wchar_t* s = sheet->readStr(2, 1);
if (s) std::wcout << s << std::endl << std::endl;
}
}
else
{
std::cout << "At first run generate !" << std::endl;
}
book->release();
}
std::cout << "\nPress any key to exit...";
_getch();
QApplication a(argc, argv);
QtGuiApplication5 w;
w.show();
return a.exec();
}
Link2019 error: Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol __imp_xlCreateBookW referenced in function main QtGuiApplication5
link1120 error: Severity Code Description Project File Line Suppression State
Error LNK1120 1 unresolved externals QtGuiApplication5 C
You need to configure visual studio project properties to use required lib. Refer this link for the same.
You are using .xlsx file so instead of xlCreateBook use xlCreateXMLBook. Apart from this you need to use using namespace libxl;as well
Below are Factory functions:
Book* xlCreateBook()
Create a binary book instance for xls format. This function should be called first for receiving a book pointer. This function and other classes are in libxl namespace.
Book* xlCreateXMLBook()
Create a xml book instance for xlsx format. This function should be called first for receiving a book pointer. This function and other classes are in libxl namespace.
See below image above code works fine at my machine.

Why including cpp makes different result

l learned "include" keyword are just copy & paste.
But including cpp file makes different compile result.
(gcc6~8 + boost1.69)
// main.cpp
#include <iostream>
// I'll move next code to why.cpp
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>
void testFunc()
{
using namespace boost::archive::iterators;
typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator>>, 8, 6> ItBinaryT;
std::string input;
std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
}
// -----------------------------
int main()
{
return 0;
}
Above code compiled without warning.
But, I replace some code with include cpp..
// main.cpp
#include <iostream>
#include "why.cpp" // <----------
int main()
{
return 0;
}
// why.cpp - just copy&paste
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>
void testFunc()
{
using namespace boost::archive::iterators;
typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator>>, 8, 6> ItBinaryT;
std::string input;
std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
}
It makes warning [-Wsubobject-linkage]
~~ has a field ~~ whose type uses the anonymous namespace
~~ has a base ~~ whose type uses the anonymous namespace
Please look at this link : https://wandbox.org/permlink/bw53IK2ZZP5UWMGk
What makes this difference?
Your compiler treats the main CPP file specially under the assumption that things defined in it are very unlikely to have more than one definition and so some tests for possible violation of the One Definition Rule are not done inside that file. Using #include takes you outside that file.
I would suggest just not using -Wsubobject-linkage since its logic is based on a heuristic that is not applicable to your code.

How do I handle errors in Lua when executing arbitrary strings?

I'm going for absolute minimalism here. (It's been a while since I've worked with the Lua C API.)
#include <lua.hpp>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv)
{
lua_State* state = luaL_newstate();
luaL_openlibs(state);
string input;
while (getline(cin, input))
{
auto error = luaL_dostring(state, input.c_str());
if (error)
{
cerr << "Lua Error: " << lua_tostring(state, -1) << '\n';
lua_pop(state, 1);
}
}
lua_close(state);
return 0;
}
This program works fine as long as I feed it perfect Lua. However, if I enter something bad (such as asdf()), the program crashes! Why is it not handling my error gracefully?
I've tried breaking out the calls before. It crashes on the call to lua_pcall itself. I never make it past that line.
The binary download (5.2.1 I believe) has a bug that was corrected in 5.2.3. I rebuilt the library from source, and now my program works fine.

Resources