errors using boost::function with boost::bind with boost::asio - boost-asio

i am facing problems combining boost::function with boost::bind and boost::asio. i am facing snippets of code down, the compiler throws tons of errors, i am pasting the root errors.
static void
startAccept(boost::asio::io_service &io,
boost::asio::ssl::context &ctx,
boost::asio::ip::tcp::acceptor &acceptor_,
const boost::system::error_code &ec
)
{
//details omitted for brevity reasons.
return;
}
boost::function<void(
boost::asio::io_service &,
boost::asio::ssl::context &,
boost::asio::ip::tcp::acceptor &,
boost::system::error_code &
)> f;
f = boost::bind(&startAccept,
boost::ref(io),
boost::ref(ctx),
boost::ref(acceptor_),
boost::asio::placeholders::error);
Errors:
In file included from as.cc:5:
In file included from /usr/local/include/boost/bind.hpp:22:
/usr/local/include/boost/bind/bind.hpp:457:93: error: no viable conversion from 'boost::asio::io_service' to
'const boost::system::error_code'
unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]);
^~~~~~~~~~~~~~~~~
/usr/local/include/boost/system/error_code.hpp:317:11: note: candidate constructor (the implicit copy constructor) not viable: no known
conversion from 'boost::asio::io_service' to 'const boost::system::error_code &' for 1st argument
class error_code
^
/usr/local/include/boost/system/error_code.hpp:317:11: note: candidate constructor (the implicit move constructor) not viable: no known
conversion from 'boost::asio::io_service' to 'boost::system::error_code &&' for 1st argument
class error_code
^
why is the compiler trying to convert boost::asio::io_service to boost::system::error_code ??

Since the signature already matches, there is no need to use boost::bind when assigning to boost::function:
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
static void startAccept(boost::asio::io_service &io, boost::asio::ssl::context &ctx,
boost::asio::ip::tcp::acceptor &acceptor_, boost::system::error_code ec) {
// details omitted for brevity reasons.
return;
}
int main() {
boost::function<void(boost::asio::io_service &, boost::asio::ssl::context &, boost::asio::ip::tcp::acceptor &,
boost::system::error_code)> f;
f = &startAccept;
}
Note that I changed the last parameter, because it was mismatched in const&/& ness. That was not the issue though.
Once you bind the first parameters, the bound signature becomes a unary function. This might be what you want to pass as a completionhandler (depending on what the completionhandler signature is supposed to be):
object.async_operation(bufs, boost::bind(f,
boost::ref(io), boost::ref(ctx), boost::ref(acceptor_),
boost::asio::placeholders::error))
In this case it's a unary completion handler, compatible with boost::function<void(boost::system::error_code)>

Related

unresolved symbol pthread_create, first referenced in ./armrtk/src/task.obj

I have been trying to figure this out for a few days now and cannot figure it out. I am using CCS as the IDE and I am working on windows. I am trying to create an RTOS Kernel on a MSP432 and need to use pthreads. I have been able to use pthreads in other examples but I am trying to do my own program and I get this issue when building :
unresolved symbol pthread_create, first referenced in ./armrtk/src/task.obj
I have included the file path into CCS and I cannot use a .cfg file because I am not using XDCTools. I just need help with this and I greatly appreciate it.
I also get a warning:
in pthread_create in TASK.C: #169-D argument of type "void *" is incompatible with parameter of type "void *(*)(void *)"
TASK.H
#ifndef TASK_H
#define TASK_H
#include <pthread.h>
struct task_t {
pthread_t* thread;
int threadCheck;
int state;
};
void *task1(void);
void *task2(void);
struct task_t *create_task(void* functionptr);
void delete_task(void *task);
#endif
TASK.C
#include <task.h>
#include <stdlib.h>
#include <pthread.h>
#define BLOCKED -1
#define READY 0
#define RUNNING 1
int testValue1 = 0;
int testValue2 = 0;
struct task_t *new_task;
pthread_t pntr;
struct task_t *create_task(void* functionptr) {
new_task = malloc(sizeof(struct task_t));
if(!new_task)
return NULL;
//set State of the new thread to ready
new_task->state = 0;
// check to see if pthread is created
**new_task->threadCheck = pthread_create(new_task->thread, NULL, functionptr, NULL);**
if(new_task->threadCheck!= 0){
//thread failed
return NULL;
}
return new_task;
}
void delete_task(void *task) {
if(task != NULL){
free(task);
pthread_exit(NULL);
}
}
The unresolved symbol error is a linker error, not a compiler error. You have failed to link the pthreads library.
With respect to the warning functionptr is a void* where pthread_create() expects a pointer-to-function with signature void fn(void*).
Your task functions have a different signature in any case: void fn(void), so in any event you will need to cast the function pointer in the call to pthread_create() (although you are loosing a useful means of passing information into a task function by omiting the void* argument).
Modify task.h:
typedef void* (*task_t)(void);
struct task_t *create_task( task_t functionptr);
The in task.cpp
new_task->threadCheck = pthread_create( new_task->thread,
NULL,
(void (*)(void *))functionptr,
NULL ) ;
The cast in the pthread_create() call alone would supress the warning, but it bad form to pass a function pointer as a generic void* since it would prevent the compiler warning you if you were to pass anything other then a function pointer of the expected form to to the create_task()`

How to use write_ply_with_properties() with Point_set_3

I have a CGAL::Point_set_3 point set with point normal and color. I would like to save all properties to a PLY file, using write_ply_with_properties() function.
My goal is to make the full version work (see code below), but even the simple version doesn't compile, with the same error as the full version.
I work on Linux with CGAL release 4.14 and gcc 7.4.0.
Here is the code:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <tuple> // for std::tie
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;
int main(int argc, char*argv[])
{
Point_set points;
points.insert(Point(1., 2., 3.));
points.insert(Point(4., 5., 6.));
// add normal map
points.add_normal_map();
auto normal_map = points.normal_map();
// add color map
typedef Point_set::Property_map< Vector > ColorMap;
bool success = false;
ColorMap color_map;
std::tie(color_map, success) =
points.add_property_map< Vector >("color");
assert(success);
// populate normal and color map
for(auto it = points.begin(); it != points.end(); ++it)
{
normal_map[*it] = Vector(10., 11., 12.);
color_map[*it] = Vector(20., 21., 22.);
}
std::ofstream out("out.ply");
#if 1
// simple version
if(!out || !CGAL::write_ply_points_with_properties(
out,
points.points(), // const PointRange
CGAL::make_ply_point_writer(points.point_map())))
#else
// full version
if(!out || !CGAL::write_ply_points_with_properties(
out,
points.points(), // const PointRange
CGAL::make_ply_point_writer(points.point_map()),
CGAL::make_ply_normal_writer(points.normal_map()),
std::make_tuple(color_map,
CGAL::PLY_property< double >("red"),
CGAL::PLY_property< double >("green"),
CGAL::PLY_property< double >("blue"))))
#endif
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
The compilation error is:
...
/usr/include/boost/property_map/property_map.hpp:303:54: error: no match for ‘operator[]’ (operand types are ‘const CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >’ and ‘const CGAL::Point_3<CGAL::Epick>’)
Reference v = static_cast<const PropertyMap&>(pa)[k];
CGAL-4.14/include/CGAL/Surface_mesh/Properties.h:567:15: note: candidate: CGAL::Properties::Property_map_base<I, T, CRTP_derived_class>::reference CGAL::Properties::Property_map_base<I, T, CRTP_derived_class>::operator[](const I&) [with I = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Index; T = CGAL::Point_3<CGAL::Epick>; CRTP_derived_class = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >; CGAL::Properties::Property_map_base<I, T, CRTP_derived_class>::reference = CGAL::Point_3<CGAL::Epick>&]
reference operator[](const I& i)
^~~~~~~~
CGAL-4.14/include/CGAL/Surface_mesh/Properties.h:567:15: note: no known conversion for argument 1 from ‘const CGAL::Point_3<CGAL::Epick>’ to ‘const CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Index&’
How can I fix it?
The problem in your code is that you are using the method points() of CGAL::Point_set_3 which returns a range of points of type CGAL::Point_set_3::Point_range, whereas the property maps that you use (points.point_map(), etc.) are directly applied to a type CGAL::Point_set_3.
So you should simply call the write_ply_points_with_properties() on points, not on points.points().
Note also that if you store your colors on simple types (for example, using three Point_set_3 properties typed unsigned char), you can take advantage of the function CGAL::write_ply_point_set() that will automatically write all the simply-typed properties it finds, which makes it quite straightforward to use (just do CGAL::write_ply_point_set(out, points) and you're done).
One last thing that is really a detail not related to your problem, but you should avoid using the CGAL::Vector_3 for storing anything else than an actual geometric 3D vector (like colors in your case). That makes your code harder to read and is also quite an ineffective way to store colors if they are encoded as integer values between 0 and 255 (which is what unsigned char is for).

How to properly check for member at compile time with boost::hana?

I am writing a physics simulation program and I want to do the following:
I have a hana adapted struct and I want to check if this struct has member called "absorbedEnergy" at compile time using:
if constexpr ( ... )
What is the proper way of doing that in c++17 which I use?
Now using hana documentation I have came up with this:
struct HasAE { double absorbedEnergy };
struct HasNoAE {};
temaplate<typename Cell>
void irelevantFunction(Cell& cell){
auto has_absorbedEnergy = hana::is_valid(
[](auto &&p) -> decltype((void) p.absorbedEnergy) {});
if constexpr(has_absorbedEnergy(cell)) { ... }
}
HasAE cell;
HasNoAE anotherCell;
cell.absorbedEnergy = 42; //value known at runtime
irelevantFunction(cell);
irelevantFunction(anotherCell);
The thing is that this compiles just fine with g++ 7.4.0 and does what I expect but fails to compile with clang++-8. It gives an error:
constexpr if condition is not a constant expression
I suspect that this originates from the fact that argument of has_absorbedEnergy - cell is not and constant expression. Is there a way around this?
Your issue seems to be related to the requirement in the standard for the expession in if constexpr to be "contextually converted constant expression of type bool" (see this question). You can work around that by changing the if constexpr to:
if constexpr (decltype(has_absorbedEnergy(cell)){})
https://wandbox.org/permlink/hmMNLberLJmt0ueJ
Alternatively, you can use expression SFINAE to achieve what you want (see the cppreference.com documentation of std::void_t):
#include <type_traits>
#include <iostream>
template <typename, typename= std::void_t<>>
struct has_absorbedEnergy : std::false_type {};
template <typename T>
struct has_absorbedEnergy<T,
std::void_t<decltype(std::declval<T&>().absorbedEnergy)>>
: std::true_type {};
template <typename Cell>
void irelevantFunction([[maybe_unused]] Cell &cell) {
if constexpr (has_absorbedEnergy<Cell>::value)
std::cout << "Has absorbedEnergy\n";
else
std::cout << "Does not have absorbedEnergy\n";
}
struct HasAbsorbedEnergy
{ int absorbedEnergy; };
struct DoesNotHaveAbsorbedEnergy
{};
int main()
{
HasAbsorbedEnergy Has;
DoesNotHaveAbsorbedEnergy DoesNot;
irelevantFunction(Has);
irelevantFunction(DoesNot);
}
https://wandbox.org/permlink/0559JhpVQBOwHC0Z

C++ Builder Function error [bcc32 - Ambiguity error] inside dll file

I am creating a currency converter Win32 program in Embarcadero C++Builder. I wrote a function for transforming date from format specified on user PC to YYYY-MM-DD format. I need that part because of API settings.
When I have this function inside my project it works fine, but I need to have that function inside a DLL.
This is how my code looks like:
#pragma hdrstop
#pragma argsused
#include <SysUtils.hpp>
extern DELPHI_PACKAGE void __fastcall DecodeDate(const System::TDateTime DateTime, System::Word &Year, System::Word &Month, System::Word &Day);
extern "C" UnicodeString __declspec (dllexport) __stdcall datum(TDateTime dat) {
Word dan, mjesec, godina;
UnicodeString datum, datum_dan, datum_mjesec, datum_godina;
DecodeDate(dat, godina, mjesec, dan);
if (dan<=9 && mjesec<=9) {
datum_dan="0"+IntToStr(dan);
datum_mjesec="0"+IntToStr(mjesec);
}
if (dan<=9 && mjesec>9) {
datum_dan="0"+IntToStr(dan);
datum_mjesec=IntToStr(mjesec);
}
if (dan>9 && mjesec<=9) {
datum_dan=IntToStr(dan);
datum_mjesec="0"+IntToStr(mjesec);
}
if (dan>9 && mjesec>9) {
datum_dan=IntToStr(dan);
datum_mjesec=IntToStr(mjesec);
}
datum_godina=IntToStr(godina);
return datum_godina+"-"+datum_mjesec+"-"+datum_dan;
}
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
`
I've included SysUtils.hpp and declared DecodeDate() function, without those lines I have a million errors. But with code looking like this, I am getting this error, which I can't get rid of:
[bcc32 Error] File1.cpp(30): E2015 Ambiguity between '_fastcall System::Sysutils::DecodeDate(const System::TDateTime,unsigned short &,unsigned short &,unsigned short &) at c:\program files (x86)\embarcadero\studio\19.0\include\windows\rtl\System.SysUtils.hpp:3466' and '_fastcall DecodeDate(const System::TDateTime,unsigned short &,unsigned short &,unsigned short &) at File1.cpp:25'
Full parser context
File1.cpp(27): parsing: System::UnicodeString __stdcall datum(System::TDateTime)
Can you help me to get rid of that error?
The error message is self-explanatory. You have two functions with the same name in scope, and the compiler doesn't know which one you want to use on line 30 because the parameters you are passing in satisfy both function declarations.
To fix the error, you can change this line:
DecodeDate(dat, godina, mjesec, dan);
To either this:
System::Sysutils::DecodeDate(dat, godina, mjesec, dan);
Or this:
dat.DecodeDate(&godina, &mjesec, &dan);
However, either way, you should get rid of your extern declaration for DecodeDate(), as it doesn't belong in this code at all. You are not implementing DecodeDate() yourself, you are just using the one provided by the RTL. There is already a declaration for DecodeDate() in SysUtils.hpp, which you are #include'ing in your code. That is all the compiler needs.
Just make sure you are linking to the RTL/VCL libraries to resolve the function during the linker stage after compiling. You should have enabled VCL support when you created the DLL project. If you didn't, recreate your project and enable it.
BTW, there is a MUCH easier way to implement your function logic - instead of manually pulling apart the TDateTime and reconstituting its components, just use the SysUtils::FormatDateTime() function or the TDateTime::FormatString() method instead, eg:
UnicodeString __stdcall datum(TDateTime dat)
{
return FormatDateTime(_D("yyyy'-'mm'-'dd"), dat);
}
UnicodeString __stdcall datum(TDateTime dat)
{
return dat.FormatString(_D("yyyy'-'mm'-'dd"));
}
That being said, this code is still wrong, because it is not safe to pass non-POD types, like UnicodeString, over the DLL boundary like you are doing. You need to re-think your DLL function design to use only interop-safe POD types. In this case, change your function to either:
take a wchar_t* as input from the caller, and just fill in the memory block with the desired characters. Let the caller allocate the actual buffer and pass it in to your DLL for populating:
#pragma hdrstop
#pragma argsused
#include <SysUtils.hpp>
extern "C" __declspec(dllexport) int __stdcall datum(double dat, wchar_t *buffer, int buflen)
{
UnicodeString s = FormatDateTime(_D("yyyy'-'mm'-'dd"), dat);
if (!buffer) return s.Length() + 1;
StrLCopy(buffer, s.c_str(), buflen-1);
return StrLen(buffer);
}
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
wchar_t buffer[12] = {};
datum(SomeDateValueHere, buffer, 12);
// use buffer as needed...
int len = datum(SomeDateValueHere, NULL, 0);
wchar_t *buffer = new wchar_t[len];
int len = datum(SomeDateValueHere, buffer, len);
// use buffer as needed...
delete[] buffer;
allocate a wchar_t[] buffer to hold the desired characters, and then return a wchar_t* pointer to that buffer to the caller. Then export a second function that the caller can pass the returned wchar_t* back to you so you can free it correctly.
#pragma hdrstop
#pragma argsused
#include <SysUtils.hpp>
extern "C" __declspec(dllexport) wchar_t* __stdcall datum(double dat)
{
UnicodeString s = FormatDateTime("yyyy'-'mm'-'dd", dat);
wchar_t* buffer = new wchar_t[s.Length()+1];
StrLCopy(buffer, s.c_str(), s.Length());
return buffer;
}
extern "C" __declspec(dllexport) void __stdcall free_datum(wchar_t *dat)
{
delete[] dat;
}
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
wchar_t *buffer = datum(SomeDateValueHere);
// use buffer as needed...
free_datum(buffer);

Googlemock - multiple actions in WillOnce cause build error

I am already using gtest for some time but recently wanted to try out gmock. I am trying to mock class with method that returns value but also returns something in output parameter through reference. Here is my small code.
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using namespace ::testing;
class AReal
{
public:
virtual bool foo(std::vector<int>& v) const = 0;
};
class AMock : public AReal
{
public:
MOCK_CONST_METHOD1(foo, bool(std::vector<int>&));
};
class B
{
public:
B(AReal* _a) : a(_a) {}
bool foo(std::vector<int>& v) const { return a->foo(v); }
private:
AReal* a;
};
class FooTest : public Test {};
TEST_F(FooTest,
DummyTestVector) {
AMock a;
B b(&a);
std::vector<int> exp = { 1, 2, 3 };
EXPECT_CALL(a, foo(_))
.Times(1)
.WillOnce(AllOf(SetArgReferee<0>(exp), Return(true)));
std::vector<int> load;
EXPECT_TRUE(a.foo(load));
EXPECT_EQ(exp, load);
}
int main(int argc, char** argv) {
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
However, this code gives me this error.
$ g++ -Wall -Wextra -std=c++14 -I. -o test test.cpp gmock-gtest-all.cc -lpthread
test.cpp: In member function ‘virtual void FooTest_DummyTestVector_Test::TestBody()’:
test.cpp:40:61: error: no matching function for call to ‘testing::internal::TypedExpectation<bool(std::vector<int>&)>::WillOnce(testing::internal::AllOfResult2<testing::SetArgRefereeActionP<0, std::vector<int> >, testing::internal::ReturnAction<bool> >::type)’
.WillOnce(AllOf(SetArgReferee<0>(exp), Return(true)));
^
In file included from test.cpp:2:0:
gmock/gmock.h:10172:21: note: candidate: testing::internal::TypedExpectation<F>& testing::internal::TypedExpectation<F>::WillOnce(const testing::Action<F>&) [with F = bool(std::vector<int>&)]
TypedExpectation& WillOnce(const Action<F>& action) {
^
gmock/gmock.h:10172:21: note: no known conversion for argument 1 from ‘testing::internal::AllOfResult2<testing::SetArgRefereeActionP<0, std::vector<int> >, testing::internal::ReturnAction<bool> >::type {aka testing::internal::BothOfMatcher<testing::SetArgRefereeActionP<0, std::vector<int> >, testing::internal::ReturnAction<bool> >}’ to ‘const testing::Action<bool(std::vector<int>&)>&’
If I don't use AllOf but rather specify just one action, either SetArgReferee or Return, everything works just fine. The use of AllOf causes this kind of error. I have found about AllOf here gmock multiple in-out parameters SetArgReferee and basically my code is same as the answer.
After one whole afternoon of trying everything I found out it was just my stupidity. All the time I somehow thought that AllOf == DoAll. Realized it just now.