The code is compiled through and run well on vs2015, but can not be compiled and report error on gcc/g++ 7.4.0, as follows:
gcc version 7.4.0 error
#include <iostream>
#include <memory>
class AA
{
public:
template<typename R, typename... Args>
R invoke(Args... args)
{
std::cout<< __FUNCTION__ << ":" << sizeof...(args) << std::endl;
return R();
}
template<typename R, typename... Args>
R call(Args... args)
{
return this->invoke<R, Args...>(args...);
}
};
template<typename T>
class BB
{
public:
BB(): lib(new T()){}
std::shared_ptr<T> lib;
};
template<typename T, typename... Args>
BB<T> make_module(Args... args)
{
BB<T> obj;
obj.lib->call<T, Args...>(args...);
return obj;
}
int main()
{
BB<AA> obj = make_module<AA>(1, 2, 3);
return 0;
}
You call member function template call on object which depends on template parameter T - BB<T> obj; you need to use template to indicate that call is member function template:
Replace
obj.lib->call<T, Args...>(args...);
by
obj.lib->template call<T, Args...>(args...);
Related
I'm binding a type my_type
py::class_<my_type, std::shared_ptr<my_type>>(m, "MyType")
.def("__repr__", [](const my_type& o){return fmt::format("MyType: {}", o);});
as well as a std::vector with
py::bind_vector<std::vector<my_type>>(m, "MyTypeVector");
How can/should I declare MyTypeVector's __repr__ method here if I want its output to be a sequence of MyType.__repr__ for each object in the container?
it is actually very simple. py::bind_vector is just a wrapper around class_ so you can add methods to it just like you would add them to a normal class.
In your case you can just do
py::bind_vector<std::vector<my_type>>(m, "MyTypeVector")
.def("__repr__", [](const std::vector<my_type>& v) {// generate your string here;});
So for making the string representation, I generally define toString methods and the << operator in my c++ classes.
class BadData
{
// lots of stuff going on and removed here
virtual void
putMembers(std::ostream& out) const
{
out << "msg=" << >msg;
out << ", ";
out << "stack=" << stack;
}
virtual std::string
toString() const
{
std::ostringstream out;
out << "BadData(";
putMembers(out);
out << ")";
return out.str();
}
}
inline
std::ostream &operator<<(std::ostream& stream, const BadData &item)
{
stream << item.toString();
return stream;
}
We also have operator<< defined for stl collections
template<class T> inline
std::ostream& operator << (std::ostream& os, const std::vector<T>& v)
{
std::ostringstream out;
out << "Vector[";
if (v.size() > 0) {
for (auto ii = v.cbegin(); ii != v.cend() -1 ; ++ii) {
out << *ii << ", ";
}
out << v.back();
}
out << "]";
os << out.str();
return os;
}
So once you have all those operators defined, your __repr__ method can just look like
.def("__repr__", [](const std::vector<my_type>& v) {
std::stringstream stream;
stream << v;
return stream.str();
})
or in the case of your custom class, like
.def("__repr__", &::my_type::toString)
JesseC helped a lot, but someone pointed out a weakness in that approach: it forces either the classes to define their own operator<<, or the programmer to define it in the bindings (which is a problem if the class has already defined an operator<<, but doesn't match what he or she wants as their __repr__ output). The core library shouldn't need to be aware that it's getting binded and therefore shouldn't be forced to implement such method.
To that end, one can modify the operator<< on the std::vector to:
template<class T>
inline std::string vector_repr(const std::vector<T>& v){
std::ostringstream out;
out << "Vector[";
auto py_vector = py::cast(v);
const auto separator = ", ";
const auto* sep = "";
for( auto obj : py_vector ){
out << sep << obj.attr("__repr__")();
sep = separator;
}
out << "]";
return out.str();
}
along with the binding
py::bind_vector<MyTypeVector>(m, "MyTypeVector")
.def("__repr__", [](const MyTypeVector& v){
return vector_repr(v);
});
I'm getting error,
error C1113: #using failed on 'c:\program files\reference assemblies\microsoft\framework\.netframework\v4.0\system.core.dll'
When Executing following code...
MyForm.cpp
#include "Myform.h"
using namespace GUI;
[STAThreadAttribute]
int main(){
MyForm fm;
fm.ShowDialog();
return 0;
}
MyForm.h
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
this->Close();
}
Take the following example
class foo {
public:
foo() {
cout << "foo has been constructed" << endl;
}
~foo() {};
void DoSomething( int i ) {
cout << "integer = " << i << endl;
}
};
int main() {
auto b = boost::bind( &foo::DoSomething,(foo*)0,_1);
b( 250 );
}
It compiles fine( this doesn't suprise me). But when I call b(), it runs fine. How is this the case? I expected, because I wasn't creating an instance of foo that calling DoSomething would case a run time problem.
Can someone explain where the instance of foo is being created? Since when I run it, I do not see the construction message printed.
foo does not get created at all.
boost-bind takes a pointer to the function. It does not care if it is C style function, a method or class function.
When you give an object instance to boost bind it just uses this object as first parameter. Since you do not require any of the instance members within DoSomething, you do not see any effect of the NULL instance.
Try and modify your example:
class foo {
public:
std:string* test_ptr;
foo() {
test_ptr=new std::string("Test");
cout << "foo has been constructed" << endl;
}
~foo() {};
void DoSomething( int i ) {
cout << "integer = " << i << endl;
cout << this->test_ptr << endl;
this->*test_ptr = "Test2"; // this is really messy with your example
}
static void DoSomething2 ( foo* sameAsThis_ptr, int i) {
this->*test_ptr = "Test3"; // compile error
// same behavior as DoSomething1
cout << "integer = " << i << endl;
cout << sameAsThis_ptr->test_ptr << endl;
sameAsThis_ptr->*test_ptr = "Test4"; // this is really messy with your example
}
};
int main() {
auto b = boost::bind( &foo::DoSomething,(foo*)0,_1);
b( 250 );
auto c = boost::bind ( &foo::DoSomething2, (foo*)NULL; _1);
c( 300 );
}
If you want to learn more you can take a closer look at "function pointers". Boost bind is just a very sophisticated way to make use of function pointers.
It wrap function pointers to an object, making functions to objects ("object functional programming")
I'm trying to build a native extension in dart for postgresql. I have compiled the CC file in .o then in .so (shared object i guess). It's now named libpsql.so and I placed it in the the same directory as my .dart file. The first line of dart file is #import(dart-ext:libpsql); but it keeps telling me that the resources is unavailable.
My dart code
#library("psql");
#import("dart-ext:libpsql_dart");
class Database {
var mDb;
var mUser;
var mDbname;
var mPasswd;
var mHost;
var mPort;
var mTable;
//String toString() => "<PostgreSQL: $user#$_host:$_port/$_table>";
Database(host,user,passwd,dbname) : this.mUser = user, this.mHost = host, this.mPasswd = passwd, this.mDbname = dbname {
mDb = _connect(host,user,passwd,dbname);
}
}
_connect(host,user,passwd,dbname) native 'Connect';
And here is my C++ code.
#include <string.h>
#include <stdio.h>
#include <libpq-fe.h>
#include "dart_api.h"
Dart_NativeFunction ResolveName(Dart_Handle name, int argc);
DART_EXPORT Dart_Handle psql_dart_Init(Dart_Handle parent_library) {
if (Dart_IsError(parent_library)) return parent_library;
Dart_Handle result_code =
Dart_SetNativeResolver(parent_library, ResolveName);
if (Dart_IsError(result_code)) return result_code;
return Dart_Null();
}
Dart_Handle HandleError(Dart_Handle handle) {
if (Dart_IsError(handle)) Dart_PropagateError(handle);
return handle;
}
void Connect(Dart_NativeArguments args) {
Dart_EnterScope();
PGconn *conn;
const char *conninfo = "user=postgres;password=postgres;host=localhost;port=5432;dbname=reviewdb";
conn = PQconnectdb(conninfo);
/* Check to see that the backend connection was successfully made */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s",
PQerrorMessage(conn));
PQfinish(conn);
}
Dart_Handle result = HandleError(Dart_NewInteger((int64_t) conn));
Dart_SetReturnValue(args, result);
Dart_ExitScope();
}
Dart_NativeFunction ResolveName(Dart_Handle name, int argc) {
assert(Dart_IsString8(name));
const char* cname;
Dart_Handle check_error = Dart_StringToCString(name, &cname);
if (Dart_IsError(check_error)) Dart_PropagateError(check_error);
Dart_NativeFunction result = NULL;
if (strcmp("Connect", cname) == 0) result = Connect;
Dart_ExitScope();
return result;
}
Html script include
<script type="application/dart" src="web/lib/psql.dart"></script>
<script type="application/dart" src="web/test_dart.dart"></script>
And the last, my compile command line :
g++ -fPIC --verbose -I/home/{linux user}/Documents/dart/dart-sdk/include/ -lpq -I/usr/include/postgresql -c psql_dart.cc
gcc -shared -Wl,-soname,libpsql.so -o libpsql.so psql_dart.o
After testing new code i commented my function Connect like this :
void Connect(Dart_NativeArguments args) {
Dart_EnterScope();
// PGconn *conn;
// const char *conninfo = "user=postgres password=postgres host=localhost port=5432";
// conn = PQconnectdb(conninfo);
//
// /* Check to see that the backend connection was successfully made */
// if (PQstatus(conn) != CONNECTION_OK)
// {
// fprintf(stderr, "Connection to database failed: %s",
// PQerrorMessage(conn));
// PQfinish(conn);
// exit(1);
// }
// PQfinish(conn);
Dart_Handle result = HandleError(Dart_NewInteger( 0));
Dart_SetReturnValue(args, result);
Dart_ExitScope();
}
The output :
worked?
Segmentation fault (core dumped)
And I still get the SegFault any idea?
My gdb stacktrace :
Starting program: /home/<user>/Documents/dart/dart-sdk/bin/dart test_dart.dart
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
worked?
Program received signal SIGSEGV, Segmentation fault.
dart::Api::NewHandle (isolate=0x948a40, raw=0x7ffff7f80021) at runtime/vm/dart_api_impl.cc:114
114 runtime/vm/dart_api_impl.cc: No such file or directory.
(gdb) bt
#0 dart::Api::NewHandle (isolate=0x948a40, raw=0x7ffff7f80021) at runtime/vm/dart_api_impl.cc:114
#1 0x000000000042e121 in dart::Dart_Invoke (target=<optimized out>, name=0x959b90, number_of_arguments=<optimized out>, arguments=<optimized out>) at runtime/vm/dart_api_impl.cc:3543
#2 0x00000000004097ee in main (argc=<optimized out>, argv=<optimized out>) at runtime/bin/main.cc:724
After playing around some with your code and getting the postgresql-dev-9.1 package installed this is where I am. Currently it still does not run, however it is due to a linking error not due to the import itself.
Note a change to your C++ file: I renamed your initialization function from: psql_dart_Init to just psql_Init
// libpsql.cc
#include <string.h>
#include <stdio.h>
#include <libpq-fe.h>
#include "dart_api.h"
Dart_NativeFunction ResolveName(Dart_Handle name, int argc);
DART_EXPORT Dart_Handle psql_Init(Dart_Handle parent_library) {
if (Dart_IsError(parent_library)) return parent_library;
Dart_Handle result_code =
Dart_SetNativeResolver(parent_library, ResolveName);
if (Dart_IsError(result_code)) return result_code;
return Dart_Null();
}
Dart_Handle HandleError(Dart_Handle handle) {
if (Dart_IsError(handle)) Dart_PropagateError(handle);
return handle;
}
void Connect(Dart_NativeArguments args) {
Dart_EnterScope();
PGconn *conn;
const char *conninfo = "user=postgres;password=postgres;host=localhost;port=5432;dbname=reviewdb";
conn = PQconnectdb(conninfo);
/* Check to see that the backend connection was successfully made */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s",
PQerrorMessage(conn));
PQfinish(conn);
}
Dart_Handle result = HandleError(Dart_NewInteger((int64_t) conn));
Dart_SetReturnValue(args, result);
Dart_ExitScope();
}
Dart_NativeFunction ResolveName(Dart_Handle name, int argc) {
assert(Dart_IsString8(name));
const char* cname;
Dart_Handle check_error = Dart_StringToCString(name, &cname);
if (Dart_IsError(check_error)) Dart_PropagateError(check_error);
Dart_NativeFunction result = NULL;
if (strcmp("Connect", cname) == 0) result = Connect;
Dart_ExitScope();
return result;
}
And the following is my 1st dart file:
// psql.dart
#library("psql");
#import("dart-ext:psql");
class Database {
var mDb;
var mUser;
var mDbname;
var mPasswd;
var mHost;
var mPort;
var mTable;
//String toString() => "<PostgreSQL: $user#$_host:$_port/$_table>";
Database(host,user,passwd,dbname) : this.mUser = user, this.mHost = host, this.mPasswd = passwd, this.mDbname = dbname {
mDb = _connect(host,user,passwd,dbname);
}
}
_connect(host,user,passwd,dbname) native 'Connect';
And then the actual VERY minimal application (command line instead of dartium-based) to test it.
// test.dart
#import('psql.dart');
main() {
var database = new Database('localhost', 'mbutler', 'test', 'test');
if(database != null) {
print('worked?');
}
}
I used the following command to compile and link in one go and I it does work correctly. I segfault because I don't have a valid database to connect to but the following does load the native library properly:
g++ -O2 -DDART_SHARED_LIB -I/home/<user>/dart/dart-sdk/include -rdynamic -fPIC -shared libpsql.cc -lpq -I/usr/include/postgresql -o libpsql.so
(Thanks to dart-sqlite build script was able to piece together the linking I required)
I don't understand why compiler thinks PERSON is NOT a ref class:
: error C2811: 'Runner' : cannot
inherit from 'Person', a ref class can
only inherit from a ref class or
interface class
I tried....
adding mscorlib.dll to the header files: #using..etc...<> - didn't work.
making Person an abstract class - didn't work (Im glad since I imagined that to be a instantiatable?? class)
I list the two header files first. Then their cose is listed later if you need it.
PERSON.H
#pragma once
using namespace System;
ref class Person
{
private:
void copy_ptr_data(Person%);
void delete_ptr_data(void);
public:
property String^ Name;
property String^ Age;
Person(String^ name, String^ age);
Person(Person%);
Person% operator= (Person%);
bool operator==(Person%);
bool operator!=(Person%);
virtual ~Person(void);
};
RUNNER.H
#pragma once
#include "Person.h"
using namespace System;
ref class Runner : public Person
{
private:
void copy_ptr_data(Runner%);
void delete_ptr_data(void);
public:
property String^ Time;
property String^ Rank;
Runner(String^ name, String^ age, String^ time);
Runner(Runner%);
Runner% operator= (Runner%);
bool operator==(Runner%);
bool operator!=(Runner%);
~Runner(void);
};
PERSON.CPP
#include "StdAfx.h"
#include "Person.h"
Person::Person(String^ name, String^ age)
{
Name = name;
Age = age;
}
Person::Person(Person% p)
{
Name = p.Name;
Age = p.Age;
copy_ptr_data(p);
}
Person% Person::operator= (Person% p)
{
// prevent self-assignment
if (this == %p) {
return *this;
}
// deallocate/reallocate/assign dynamic memory
delete_ptr_data();
copy_ptr_data(p);
// assign non-dynamic memory
Name = p.Name;
Age = p.Age;
return *this;
}
bool Person::operator==(Person% p)
{
if ((Name == p.Name) &&
(Age == p.Age))
return 1;
return 0;
}
bool Person::operator!=(Person% p)
{
return !(Person::operator==(p));
}
Person::~Person(void)
{
delete_ptr_data();
}
void Person::copy_ptr_data(Person% p)
{
return;
}
void Person::delete_ptr_data()
{
return;
}
RUNNER.CPP
#include "StdAfx.h"
#include "Runner.h"
Runner::Runner(String^ name, String^ age, String^ time) : Person(name, age)
{
Time = time;
Rank = nullptr;
}
Runner::Runner(Runner% r) : Person(r)
{
Time = r.Time;
Time = r.Rank;
copy_ptr_data(r);
}
Runner% Runner::operator= (Runner% r)
{
// handle self assignment
if (this == %r) return *this;
// handle base class portion
Person::operator=(r);
// handle dynamic portion
delete_ptr_data();
copy_ptr_data(r);
// handle non-dynamic portion
Time = r.Time;
Rank = r.Rank;
return *this;
}
bool Runner::operator==(Runner% r)
{
if ((Person::operator==(r)) &&
(Time == r.Time) &&
(Rank == r.Rank))
return 1;
return 0;
}
bool Runner::operator!=(Runner% r)
{
return !(Runner::operator==(r));
}
Runner::~Runner(void)
{
}
void Runner::copy_ptr_data(Runner% r)
{
return;
}
void Runner::delete_ptr_data()
{
return;
}
Shouldn't you be putting:
#using <mscorlib.dll>
at the top of your header files? I'm not sure if that would fix the issue to be honest.
Try making your Person class abstract.