What is the meta information in a *_DCPS.hpp file generated from an IDL (using cyclonedds-cxx)? - metadata

I use cyclonedds-cxx and their IDL compiler to translate IDL files for the use with cyclonedds-cxx. I have this IDL file:
#ifndef TRANSPORTDATA_IDL
#define TRANSPORTDATA_IDL
#include "Transform_.idl"
module TransportData
{
struct Data
{
long userID; //#key
geometry_msgs::msg::dds_::Transform_ transform_;
};
#pragma keylist Data userID
};
#endif // TRANSPORTDATA_IDL
This IDL file is, among others, converted to Transportdata_DCPS.hpp, which looks like this:
#ifndef ISOCPP2_TRANSPORTDATA_H
#define ISOCPP2_TRANSPORTDATA_H
#include "dds/dds.hpp"
#include "TransportData.h"
#include "TransportDataSplDcps.h"
#include "org/eclipse/cyclonedds/topic/TopicTraits.hpp"
#include "org/eclipse/cyclonedds/topic/DataRepresentation.hpp"
namespace org { namespace eclipse { namespace cyclonedds { namespace topic {
template <>
class TopicTraits<TransportData::Data>
{
public:
static ::org::eclipse::cyclonedds::topic::DataRepresentationId_t getDataRepresentationId()
{
return ::org::eclipse::cyclonedds::topic::OSPL_REPRESENTATION;
}
static ::std::vector<uint8_t> getMetaData()
{
return ::std::vector<uint8_t>();
}
static ::std::vector<uint8_t> getTypeHash()
{
return ::std::vector<uint8_t>();
}
static ::std::vector<uint8_t> getExtentions()
{
return ::std::vector<uint8_t>();
}
static const char *getKeyList()
{
return "userID";
}
static const char *getTypeName()
{
return "TransportData::Data";
}
static const dds_topic_descriptor_t *getDescriptor()
{
return &TransportData_Data_desc;
}
static copyInFunction getCopyIn()
{
return (copyInFunction) __TransportData_Data__copyIn;
}
static copyOutFunction getCopyOut()
{
return (copyOutFunction) __TransportData_Data__copyOut;
}
static size_t getSampleSize()
{
return sizeof(TransportData_Data);
}
};
}}}}
namespace dds { namespace topic {
template <>
struct topic_type_name<TransportData::Data>
{
static std::string value()
{
return org::eclipse::cyclonedds::topic::TopicTraits<TransportData::Data>::getTypeName();
}
};
}}
REGISTER_TOPIC_TYPE(TransportData::Data)
#endif /* ISOCPP_TRANSPORTDATA_H */
I have three questions about this:
Where can I find a documentation of the meta information?
Is this meta information guaranteed to be there by the DDS standard?
What are the copyInFunctionand the copyOutFunction for?

This is all implementation-specific and with the new IDL compiler for Cyclone, the output will change completely, even eliminating most of the generated files.
The copyInFunction and copyOutFunction here refer to functions that copy samples from the C++ representation to an internal representation and back. For the initial commit of the C++ API, this internal representation is actually the sample in C representation, after which it gets converted to/from CDR. The new version does away with these functions and avoids this copy.

Related

boost.python MSVC12 linker errors when exposing classes with docstring_options

I regularly expose c++ classes to python using boost.python & MSVC 12 (dynamic linking). Recently I have been trying to include documentation using the "docstring_options" class. The documentation examples work fine:
http://www.boost.org/doc/libs/1_54_0/libs/python/doc/v2/docstring_options.html
However, when I include a class and expose it I get linker errors:
error LNK2019: unresolved external symbol "void __cdecl boost::throw_exception(class std::exception const &)" (?throw_exception#boost##YAXABVexception#std###Z) referenced in function "public: __thiscall boost::detail::shared_count::shared_count(void *,struct boost::python::converter::shared_ptr_deleter)"
I'm sure there is probably something simple I'm missing but I can't figure it out.
Many thanks in advance!
sample code spliced from the boost examples that gives this error for me.
#include <string>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/args.hpp>
#include <boost/python/docstring_options.hpp>
#include <boost/python.hpp>
struct World
{
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
int foo1(int i) { return i; }
int foo2(long l) { return static_cast<int>(l); }
int bar1(int i) { return i; }
int bar2(long l) { return static_cast<int>(l); }
namespace {
void wrap_foos()
{
using namespace boost::python;
def("foo1", foo1, arg("i"), "foo1 doc");
def("foo2", foo2, arg("l"), "foo2 doc");
}
void wrap_bars()
{
using namespace boost::python;
bool show_user_defined = true;
bool show_signatures = false;
docstring_options doc_options(show_user_defined, show_signatures);
def("bar1", bar1, arg("i"), "bar1 doc");
def("bar2", bar2, arg("l"), "bar2 doc");
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
}
}
BOOST_PYTHON_MODULE(boost_py_doc_demo)
{
boost::python::docstring_options doc_options(false);
wrap_foos();
wrap_bars();
}
I compiled the latest version of boost (1.63) and now the problem has gone. I guess my old libraries were incomplete in some way.

Unmanaged method member being used as a delegate in managed class

I have a project where I am expanding existing native C++ compatible code functionality for a customer-facing library by integrating a driver from a managed DLL, which seems like the opposite direction for most marshaling questions. Since there can be multiple devices using this one driver, each device needs to be its own object, with its own callback methods. This integration will take the form of a native wrapper DLL that exposes the native class interface to the customer-facing library, which will pass an instance of a member method callback function pointer to the DLL. I need to pass a native method member instance (non-static) as a delegate to the managed wrapper class. The managed wrapper class uses GetDelegateForFunctionPointer, which works to marshal static native pointers to a delegate, but I can't find any information if it works with instances. GetDelegateForFunctionPointer also takes a System::IntPtr argument for the function pointer, but I'm also not sure if System::IntPtr works for instances, and when compiling in VC++2008 I'm being presented an error C3867 for attempting this.
Managed wrapper header:
//somemanagedclass.hpp
#pragma once
using namespace System;
using namespace ExternalManagedLibrary;
namespace SomeNameSpace
{
public ref class SomeManagedClass
{
public:
SomeManagedClass();
~SomeManagedClass();
delegate void CallbackHandler(const wchar_t*, int);
CallbackHandler^ CallbackEvent;
void RegisterCallback(IntPtr callbackEvent);
private:
ExternalManagedClass^ externalManagedClass;
void OnCallback(Object^ sender, ValueEventArgs<String^>^ e);
};
}
Managed wrapper source:
//somemanagedclass.cpp
#include "somemanagedclass.hpp"
#include <vcclr.h>
using namespace System;
using namespace Runtime::InteropServices;
namespace SomeNameSpace
{
SomeManagedClass::SomeManagedClass()
{
externalManagedClass = gcnew ExternalManagedClass();
externalManagedClass->CallbackEvent += gcnew EventHandler<ValueEventArgs<String^>^>(this, &SomeManagedClass::OnCallback);
}
SomeManagedClass::~SomeManagedClass()
{
externalManagedClass->CallbackEvent -= gcnew EventHandler<ValueEventArgs<String^>^>(this, &SomeManagedClass::OnCallback);
}
void SomeManagedClass::OnCallback(Object^ sender, ValueEventArgs<String^>^ e)
{
String^ some_string = String::Copy(e->Value);
cli::pin_ptr<const wchar_t> pinned_string = &PtrToStringChars(some_string)[0];
const wchar_t* p = pinned_string;
CallbackEvent(pinned_string, some_string->Length);
}
void SomeManagedClass::RegisterCallback(IntPtr callbackEvent)
{
CallbackEvent = (CallbackHandler^)(Marshal::GetDelegateForFunctionPointer(callbackEvent, CallbackHandler::typeid));
}
}
Native wrapper interface:
//somenativeinterface.hpp
#ifdef DLL_EXPORT
#define IMPORT_EXPORT __declspec(dllexport)
#else
#define IMPORT_EXPORT __declspec(dllimport)
#endif //DLL_EXPORT
typedef void (*NativeCallback)(const unsigned char*, unsigned long);
class IMPORT_EXPORT SomeNativeInterface
{
public:
//class factory
static SomeNativeInterface* Create(void);
static void Destroy(SomeNativeInterface* clInterface);
virtual void CallbackInit(NativeCallback fnNativeCallbackInit);
};
Native wrapper header:
//somenativeclass.hpp
#pragma once
#include "somenativeinterface.hpp"
#include "somemanagedclass.hpp"
#include <vcclr.h>
using namespace SomeNameSpace;
class IMPORT_EXPORT SomeNativeClass : public SomeNativeInterface
{
public:
SomeNativeClass();
~SomeNativeClass();
void CallbackInit(NativeCallback fnNativeCallbackInit); //can this take an instance?
private:
NativeCallback fnNativeCallback;
void OnNativeCallback(const wchar_t* cString, int iSize);
gcroot<SomeManagedClass^> wrapper; //warning C4251
};
Native wrapper source:
//somenativeclass.cpp
#include "somenativeclass.hpp"
#include <vcclr.h>
#include <string.h>
using namespace System;
using namespace Runtime::InteropServices;
SomeNativeInterface* SomeNativeInterface::Create()
{
return ((SomeNativeInterface*) new SomeNativeClass());
}
void SomeNativeInterface::Destroy(SomeNativeInterface* instance)
{
delete instance;
}
SomeNativeClass::SomeNativeClass()
{
wrapper = gcnew SomeManagedClass();
}
SomeNativeClass::OnNativeCallback(const wchar_t* cString, int iSize)
{
std::auto_ptr<char> pcConvertedString(new char[iSize+1]);
size_t iCharsConverted;
if (wcstombs_s(&iCharsConverted, (char*)*pcConvertedString, iSize+1, cString, iSize) == 0)
{
if (iCharsConverted > 0xFFFFFFFF)
iCharsConverted = 0xFFFFFFFF; //truncate
fnNativeCallback((const unsigned char*)*pcConvertedString, (unsigned long)(iCharsConverted));
}
}
SomeNativeClass::CallbackInit(NativeCallback fnNativeCallbackInit)
{
fnNativeCallback = fnNativeCallbackInit;
wrapper->RegisterCallback(System::IntPtr(this->OnNativeCallback)); //error C3867
}

Visual C++ not know function return value which is a user defined class

I have,
time.h:
#pragma once
#ifndef TIME_H
#define TIME_H
class time
{
private:
int hour;
int minute;
int second;
public:
enum pmORam {am,pm};
time(void);
time(int,int,int);
void printtime(void);
time subtime(time &);
const time &operator=(const time &);
void setTime(int,int,int);
~time(void);
};
#endif
time.cpp:
#include <iostream>
#include <iomanip>
#include "stdafx.h"
#include "time.h"
using namespace std;
time::time(void)
{
hour=0;
minute=0;
second=0;
}
time::time(int hr,int min,int sec)
{
setTime(hr,min,sec);
}
void time::printtime(void)
{
enum pmORam p;
if(hour<=12 && hour>=0)
cout<<setfill('0')<<setw(2)<<hour<<":"<<setw(2)<<minute<<":"<<setw(2)<<second<<p.am<<endl;
else
if(hour>12 && hour<=23)
{
hour=hour%12;
cout<<setfill('0')<<setw(2)<<hour<<":"<<setw(2)<<minute<<":"<<setw(2)<<second<<p.pm<<endl;
}
}
const time &time::operator=(const time &t)
{
hour=t.hour;
minute=t.minute;
second=t.second;
return *this;
}
time time::subtime(time &m)
{
if(hour>m.hour)
{
if(m.second>second)
{
minute=minute-1;
second=(second+60)-m.second;
}
second=second-m.second;
if(m.minute>minute)
{
hour=hour-1;
minute=(minute+60)-m.minute;
}
minute=minute-m.minute;
hour=hour-m.hour;
}
if(second>m.second)
{
m. minute=m.minute-1;
m.second=(m.second+60)-second;
}
m.second=m.second-second;
if(minute>m.minute)
{
m.hour=m.hour-1;
m.minute=(m.minute+60)-minute;
}
m.hour=hour-m.hour;
return *this;
}
void time::setTime(int hr,int min,int sec)
{
hour=(hr>=0 && hr<=23)? hr: 0;
minute=(min>=0 && min<60)? min:0;
second=(sec>=0 && sec<60)? sec:0;
}
time::~time(void)
{
}
But in time.cpp i get to this Errors:
IntelliSense: declaration is incompatible with "time time::subtime(time &)"
IntelliSense: declaration is incompatible with "const time &time::operator=(const time &)"
'time::time(const time &)' : cannot convert parameter 1 from 'time *const ' to 'const time &'
'int time::subtime(time &)' : overloaded function differs only by return type from 'time time::subtime(time &)'
'int &time::operator =(const time &)' : overloaded function differs only by return type from 'const time &time::operator =(const time &)'
function "time" is not a type name
What is Problem?
Edit: New code to fix naming conflict
time.cpp:
#include <iostream>
#include <iomanip>
#include "stdafx.h"
#include "time.h"
using namespace std;
timea::timea(void)
{
hour=0;
minute=0;
second=0;
}
timea::timea(int hr,int min,int sec)
{
setTime(hr,min,sec);
}
void timea::printtime(void)
{
enum timea::pmORam p;
if(hour<=12 && hour>=0)
cout<<setfill('0')<<setw(2)<<hour<<":"<<setw(2)<<minute<<":"<<setw(2)<<second<<p.am<<endl;
else
if(hour>12 && hour<=23)
{
hour=hour%12;
cout<<setfill('0')<<setw(2)<<hour<<":"<<setw(2)<<minute<<":"<<setw(2)<<second<<p.pm<<endl;
}
}
const timea &timea::operator=(const timea &t)
{
hour=t.hour;
minute=t.minute;
second=t.second;
return *this;
}
timea timea::subtime(timea &m)
{
if(hour>m.hour)
{
if(m.second>second)
{
minute=minute-1;
second=(second+60)-m.second;
}
second=second-m.second;
if(m.minute>minute)
{
hour=hour-1;
minute=(minute+60)-m.minute;
}
minute=minute-m.minute;
hour=hour-m.hour;
}
if(second>m.second)
{
m. minute=m.minute-1;
m.second=(m.second+60)-second;
}
m.second=m.second-second;
if(minute>m.minute)
{
m.hour=m.hour-1;
m.minute=(m.minute+60)-minute;
}
m.hour=hour-m.hour;
return *this;
}
void timea::setTime(int hr,int min,int sec)
{
hour=(hr>=0 && hr<=23)? hr: 0;
minute=(min>=0 && min<60)? min:0;
second=(sec>=0 && sec<60)? sec:0;
}
timea::~timea(void)
{
}
There's a header file in the Standard library named time.h. It's likely that either
You're including the system header file when you wanted your own, or
System header files are pulling in yours when they wanted the standard one
or both. Find a different name for your header.
In addition, the identifier time in the global namespace is used by a function in the Standard library (hence the error function "time" is not a type name). So put yours inside a namespace or change the class name.
Specifically, your errors are caused by ignoring this rule, found in 17.6.4.3.3:
Each name from the Standard C library declared with external linkage is reserved to the implementation for use as a name with extern "C" linkage, both in namespace std and in the global namespace.
Each function signature from the Standard C library declared with external linkage is reserved to the implementation for use as a function signature with both extern "C" and extern "C++" linkage, or as a name of namespace scope in the global namespace.

Access to the same class instance from qml

I'm using Qt 5.1.0 and QtQuick 2.0.
I've just learned how to exchange data and method between qml and C++. In detail, I want to expose a (nested) structure, so I created classes which contains the required properties and methods.
It works, but I cannot share the very same instance between C++ and qml. Changing something from C++ side leads to no changes in qml side.
A short example:
main.cpp
#include <QtGui/QGuiApplication>
#include <QtQml>
#include "qtquick2applicationviewer.h"
#include "myclass.h"
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
qmlRegisterType<MyClass>("MyLibrary", 1, 0, "MyClass");
MyClass *myclass = new MyClass();
Category *cat = new Category();
cat->setName("foo");
myclass->append(cat);
qDebug() << myclass->categoriesCount(); // returns 1 OK!
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/main.qml"));
viewer.show();
return app.exec();
}
myclass.h
#include <QObject>
class Category : public QObject {
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName)
public:
Category() {}
QString name() const { return m_name; }
void setName(QString name) { m_name = name; }
private:
QString m_name;
};
class MyClass : public QObject {
Q_OBJECT
Q_PROPERTY(QList<QObject*> categories READ categories NOTIFY categoriesChanged)
Q_PROPERTY(int categoriesCount READ categoriesCount)
public:
QList<QObject*> categories() const { return m_categories; }
void clear() { m_categories.clear(); }
void append(Category *category) { m_categories.append(category); }
int categoriesCount() const { return m_categories.count(); }
private:
QList<QObject*> m_categories;
signals:
void categoriesChanged();
};
main.qml
import QtQuick 2.0
import MyLibrary 1.0
Item {
id: root
width: 360
height: 360
Text {
id: foo
text: myclass.categoriesCount // writes 0 -> should be 1
}
MyClass {
id: myclass
}
}
I'm afraid the qml engine accesses to a different instance of the class myclass created in the main file.

Is it possible to point a Typedef function pointer to a class member?

I am working with an executable that includes a DLL. For my testcase, I combined the code into a single executable. I am working with Visual Studio 2008 and Boost 1.43. I've tried researching this, but haven't found any clear answer. Thanks for the help.
In my main.h:
#include <string>
//These are normally defined in a seperate DLL
typedef std::string Typedef_func(const std::string & title);
void Register_My_Typedef(Typedef_func*);
//-------------------------------------------
class myClass
{
public:
std::string func_one(const std::string & title);
Typedef_func _test;
void run();
};
In my main.cpp:
#include "main.h"
#include <boost/bind.hpp>
std::string workingFunc(const std::string & title)
{
return "";
}
int main(int argc, char* argv[])
{
myclass* example;
example->run();
Register_My_Typedef(&workingFunc);//This works.
return 0;
}
void myClass::run()
{
//I want to point a Typedef_func* in a DLL to call myclass::func_one
Typedef_func* tf = boost::bind(&myClass::func_one, this, "test"); //This does not.
Register_My_Typedef(tf);
}
std::string myClass::funcOne(const std::string & title)
{
return "";
}
void Register_My_Typedef(Typedef_func* passedIn)
{
//Points the pointer in the DLL to passedIn
}
The DLL logic works fine when Register_My_Typedef is called on a function not in a class, but is it possible to call it from within a class? When I try to compile this code it returns:
When I try and compile in Windows XP with VS2008 I get:
Error C2440: 'initializing' : cannot convert from
'boost::_bi::bind_t' to 'Typedef_func (__cdecl *)' with
[
R=std::string,
F=boost::_mfi::mf1,
L=boost::_bi::list2,boost::_bi::value>
]
No user-defined-conversion operator available that can perform this
conversion, or the operator cannot be called.
The Answer is Typedef itself is class member for a static member function & behave differently to non-static however works best reading rather class function of user defined class main.