I would like to use boost::shared_ptr<> to encapsulate the lifetime management of a handle. My handle and it's creation/destruction functions are declared like this:
typedef const struct MYHANDLE__ FAR* MYHANDLE;
void CloseMyHandle( MYHANDLE );
MYHANDLE CreateMyHandle();
Ideally, I would like to use the boost::shared_ptr<> like this to manage the handle:
boost::shared_ptr< void > my_handle( CreateMyHandle(), &CloseMyHandle );
Unfortunately, because the handle is declared as a const struct * instead of the usual void *, I get errors like this:
boost/smart_ptr/shared_ptr.hpp(199) : error C2440: 'initializing' : cannot convert from 'const MYHANDLE__ *' to 'void *'
I can use a functor to cast the void * to a MYHANDLE like this:
struct DeallocateMyHandle
{
void operator()( void* handle )
{
CloseMyHandle( ( MYHANDLE )handle );
};
};
boost::shared_ptr< void > my_handle( ( void* )CreateMyHandle(), DeallocateMyHandle() );
But, I'd rather have a method that doesn't involve the separate functor. Is there a way to do this just within the boost::shared_ptr<> constructor that I'm not seeing? Or, am I stuck with the functor?
Thanks,
PaulH
Why not use:
boost::shared_ptr< const MYHANDLE__ > my_handle( CreateMyHandle(), &CloseMyHandle );
PS. Note the use of double underscore is not allowed (it is reserved for the implementation).
See: Rules about identifers
If HANDLE is a public type, but the type it points to is not, there's a really easy way to write this:
template <typename T> struct unpointer { };
template <typename T> struct unpointer<T*> { typedef T type; };
boost::shared_ptr<typename unpointer<MYHANDLE>::type> my_handle(
CreateMyHandle(), &CloseMyHandle);
(If you're using a really old version of VC++ or gcc you probably have to omit the "typename" there.)
Of course this gets a bit verbose and tedious. If you're only got one handle type to deal with, you probably to write this:
typedef typename unpointer<MYHANDLE>::type MYHANDLEREF;
typedef boost::shared_ptr<MYHANDLEREF> my_shared_ptr;
If you've got all kinds of handles to wrap (and since it looks like you're doing Win32 API stuff, you probably do), create a template that wraps things up at whatever level you prefer (a class template that just generates the types, a handle_ptr<T> that subclasses shared_ptr<unpointer<T>> and adds the default deleted for you, a handle_ref<T> that uses a shared_ptr behind the scenes to fake being a MYHANDLE & instead of faking being what MYHANDLE is a pointer to, etc.)
Your shared_ptr type needs to be this:
boost::shared_ptr< const MYHANDLE__ FAR>
That way when shared_ptr makes a pointer out of it, it becomes:
const MYHANDLE__ FAR*
Which matches your MYHANDLE type exactly:
#include <boost/shared_ptr.hpp>
struct MYHANDLE__ {};
typedef const MYHANDLE__* MYHANDLE;
void CloseMyHandle(MYHANDLE) {}
MYHANDLE CreateMyHandle(void) { return 0; }
int main()
{
typedef boost::shared_ptr<const MYHANDLE__> ptr_type;
ptr_type my_handle( CreateMyHandle(), &CloseMyHandle );
}
Note, I really doubt you need FAR, that's from the 16-bit ages. It expands to either far or nothing, depending on if you're compiling for 16-bit (hint: you aren't compiling to 16-bit. :) ). far isn't even an extension anymore, as far as I know.
Also, like Martin said don't use double-underscores anywhere.
Related
I try to implement a Java-Like annotation system using boost MPL and fusion.
Why is it needed:
I need to annotate member var's to have some special runtime features.
I register try them at compile time to my base clase like this:
class foo
{
INIT()
$REGISTER("test1")
int test1 = 5;
$REGISTER("b")
char* b = "rndmText";
....
}
My target is a combination of a pointer and a text like $REGISTER(&a,"a") but that's the future target...
The Base class handle all the necessary stuff.
The register macro create a fusion vector:
#define INIT() \
typedef boost::fusion::vector0<> BOOST_PP_CAT(registered, BOOST_PP_SUB(__COUNTER__,2)); \
boost::fusion::vector0<> BOOST_PP_CAT(list,BOOST_PP_SUB(__COUNTER__,2));
#define EXPORT(arg) \
typedef boost::fusion::result_of::push_back< BOOST_PP_CAT(registered, BOOST_PP_SUB(__COUNTER__,4)), const char*>::type BOOST_PP_CAT(registered, __COUNTER__); \
BOOST_PP_CAT(registered, BOOST_PP_DEC(__COUNTER__)) BOOST_PP_CAT(list, BOOST_PP_SUB(__COUNTER__,1)) = boost::fusion::make_list(BOOST_PP_CAT(list,BOOST_PP_SUB(__COUNTER__,7)), arg);
This expands (in my case) to:
typedef boost::fusion::vector0<> registered18;
boost::fusion::vector0<> list19;;
typedef boost::fusion::result_of::push_back< registered18, const char*>::type registered23;
registered23 list24 = boost::fusion::make_list(list19, "test1");;
int test1 = 5;
typedef boost::fusion::result_of::push_back< registered23, const char*>::type registered28;
registered28 list29 = boost::fusion::make_list(list24, "b");;
char* b = "rndmText";;
And here is the Problem:
boost::fusion::make_list(..., "test1") create a compiler error and i don't know how to fix it. This is the error:
boost::fusion::joint_view<Sequence,const boost::fusion::single_view<const char *>>::joint_view(const boost::fusion::joint_view<Sequence,const boost::fusion::single_view<const char *>> &)' : cannot convert argument 1 from 'boost::fusion::list<T,const char (&)[6],boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_>' to 'const boost::fusion::joint_view<Sequence,const boost::fusion::single_view<const char *>> &'
Can someone help me or have a better idea?
Dominik
This is not really help with the compilation error (sorry) but it was too long for a comment.
Can someone help / or have a better idea?
I think you are abusing macros. Consider this client code instead:
class foo: public registered<foo> {
int test1 = 5;
char* b = "rndmText";
public:
foo();
virtual ~foo() = default;
};
foo::foo() : registered<foo>{ "foo" } {
register(&i, "i"); // part of the interface of the base class
register(&b, "b");
}
Explanation:
The same functionality is now provided by a base class. The CRTP implementation means that if you have two (or more) classes inheriting from registered, they are not in the same class hierarchy (because the adition of metadata should not impose a class relationship between unrelated concrete classes).
The implementation of registered<T> could use boost::fusion internally (or something else if you need it) and could hide the three meters long declarations behind a handy alias (e.g. using data_sequence = boost::fusion::vector0<>).
The INIT() part will go naturally in the construction of registered<T> instance (and public interface).
This implementation avoids macros completely and allows you to expose metadata to client code in a more elegant way, maybe by simply importing from the API of registered<T>.
I'm really not sure how do i serialize a list variable of type boost::shared_ptr <void *> inside a class or struct. Generally, i would go with same method that we generally use like
struct A
{
std::list<boost::shared_ptr<void *>> mdb;
}
template<class Archive>
void serialize(Archive &d,const unsigned int version)
{
d & mdb; // not sure that this would work
}
while compiling it does not give error but does not serialize at my end.
You don't. In all likelihood, the void* is
a HANDLE (for some native API); you can serialize this only if the API has enough identifying information to reconstruct the handle on load
a type pun for something else (this would be silly, just have the real type there, then)
We have a big, old C++ application with a lot of legacy code and a few external libraries written in C. These libraries are very rarely updated - only if we find a bug and the vendor supplies a patch. This happened last week with one library, and upon integrating the new version we found out that if we don't modify the library locally (which we apparently did with the last version) our build breaks with this error message:
non-local function ‘static E* MyCls::myFct(<anonymous struct>*)’ uses anonymous type
This is due to the library declaring a number of handle types like this:
#define _Opaque struct {unsigned long x;} *
typedef _Opaque Handle;
typedef _Opaque Request;
which we use on our side in some classes' function signatures:
class MyCls {
public:
static void* myFct(Handle handle);
...
}
This produces the error above because the compiler can't create a proper name-mangled name for the function(s) as the _Opaque struct has no name.
Our current workaround for this is to patch the library header file, explicitly giving the struct a name:
//#define _Opaque struct {unsigned long x;} * //Replaced by typedef below!
typedef struct __Opaque {unsigned long x;} * _Opaque;
This is obviously bad because we don't want to touch the library if possible. Another even worse option would be to convert the types to void* in all function signatures and cast them back to their respective types. And there's the worst option to rewrite every affected function in pure C...
So, my question is: Is there any better option than patching the library? Is there an easy solution I am overlooking? What would be the best way to solve this?
You can accomplish this with a minimal change to the #define line, exploiting the rule in 7.1.3:8 that the first typedef-name declared by the declaration to be
that class type (or enum type) is used to denote the class type (or enum type) for linkage purposes only:
#define MAKE_DUMMY2(line) dummy_ ## line
#define MAKE_DUMMY(line) MAKE_DUMMY2(line)
#define _Opaque struct {unsigned long x;} MAKE_DUMMY(__LINE__), *
This gives Handle and Request etc. minimal linkage.
You can introduce names by declaring new types, which simply contain these elements. Use those types for your parameters.
namespace MON {
struct t_handle {
Handle handle;
};
class MyCls {
public:
static void* myFct(t_handle handle);
...
};
}
If you're willing to modify your methods on the interface, you can do slightly better than void *:
struct CHandle {
void *p;
CHandle(void *p): p(p) { }
};
struct CRequest {
void *p;
CRequest(void *p): p(p) { }
};
static CHandle make(Handle handle) { return CHandle(handle); }
static Handle get(CHandle handle) { return static_cast<Handle>(handle.p); }
static CRequest make(Request request) { return CRequest(request); }
static Request get(CRequest request) { return static_cast<Request>(request.p); }
Here, CHandle and CRequest have linkage and so can be used in your method signatures; the overloads of make and get have internal linkage and so can interface with the anonymous types. You can put this in a header, even the static functions.
You'll have to modify your code so that when e.g. MyCls::myFct calls into the library, you wrap parameters with get and return values with make.
This seems to work:
class MyCls {
public:
typedef _Opaque MHandle;
static void* myFct(MHandle handle) {
return 0;
}
};
I have an OracleConnection class that uses the OCCI Oracle API to access the database. I now need to go fetch multiple rows of records from the database and this is done with the ResultSet::getDataBuffer(...) function of the API. This function takes a series of arguments, one of them being a big enum which defines the types of data can contain.
Obviously I don't want to strew my application code with Oracle API types, so other API's could be interchanged with this one. So my question is how would I best take this Type parameter in my function wrapper? Should I just create an enum and take only the types I will need or could templates help me here to map to the enum of OCCI in the OracleConnection class I have?
Occi setDataBuffer function:
void setDataBuffer(
unsigned int colIndex,
void *buffer,
Type type,
sb4 size = 0,
ub2 *length = NULL,
sb2 *ind = NULL,
ub2 *rc = NULL);
Type here is an enum that looks like this:
enum Type
{
OCCI_SQLT_CHR=SQLT_CHR,
OCCI_SQLT_NUM=SQLT_NUM,
OCCIINT = SQLT_INT,
OCCIFLOAT = SQLT_FLT,
OCCIBFLOAT = SQLT_BFLOAT,
OCCIBDOUBLE = SQLT_BDOUBLE,
OCCIIBFLOAT = SQLT_IBFLOAT,
OCCIIBDOUBLE = SQLT_IBDOUBLE,
OCCI_SQLT_STR=SQLT_STR,
OCCI_SQLT_VNU=SQLT_VNU,
OCCI_SQLT_PDN=SQLT_PDN,
OCCI_SQLT_LNG=SQLT_LNG,
OCCI_SQLT_VCS=SQLT_VCS,
.... (about 2x as many to go)
my wrapper looks as follows:
void setDataBuffer(unsigned int colIndex, void * buffer, unsigned long size = 0, int type /*use int or template or redefine own Type Enum?*/, unsigned short * length = NULL, signed short * ind = NULL, unsigned short * rc = NULL)
One option could be to make your function a template, and then use a traits class to convert the template type to the values representing the various Oracle types.
The traits class could look like this:
template <typename T>
struct oracle_type_traits;
template <> // create a specialization for each relevant type
struct oracle_type_traits<double> {
static const value = OCCIBDOUBLE // its value member should be the value you want to map to
};
Now, the following will give you the Oracle type id for a double:
oracle_type_traits<double>::value
and inside setDataBuffer<T>(...), you just check oracle_type_traits<T>::value to get the corresponding Oracle type ID.
From the POV of the users of your wrapper, the best would be if they would call either an overloaded function or a function (member) template that they pass an object to of the appropriate type and which will then magically do the right thing for that type. That is, the best would be to have a function getData(unsigned int colIndex, T&) for any type T your class (or the Oracle API) supports, which will find out the necessary buffer size, allocate the buffer, determine the right enum, and call the Oracle API function.
I'm sure you can work out most of the details, probably with the exception of how to map a type to the enum, so this is what I'll try to line out.
Basically, I see two possibilities for this, one of which (employing a compile-time list) is better suited if you have lots of types to support, while the other one (employing traits) needs to be used if there's more type-specific to this than just mapping a type to an enum.
The traits method is quite simple to use, but tedious if you have many types:
template<typename T>
struct get_data_buffer_traits;
template<>
struct get_data_buffer_traits<int> {
Type type OCCIINT;
};
template<>
struct get_data_buffer_traits<float> {
Type type OCCIBFLOAT;
};
You can then map the type passed to your template as T into the right enum value using get_data_buffer_traits<T>::type.
This traits template is also the place where you can put any other type-specific operation your generic data retrieval function might need (like converting between what's in the buffer and the actual type, if that isn't a straight-forward cast). If you don't have anything else to put into these traits, you could use a macro to make defining these easier:
#define DEFINE_GET_DATA_BUFFER_TRAITS(Type_,Enum_) \
template<> struct get_data_buffer_traits<Type_> { Type type Enum_; };
DEFINE_GET_DATA_BUFFER_TRAITS(int , OCCIINT );
DEFINE_GET_DATA_BUFFER_TRAITS(float, OCCIBFLOAT);
...
#undef DEFINE_GET_DATA_BUFFER_TRAITS
However, if that's the case, you might as well create a compile-time map that maps the two and search that (at compile-time) for the right enum value. If you don't have a template meta library at hand that provides this, here's the outline for an idea how to do that yourself:
// Beware, brain-compiled code ahead!
struct nil {};
template< typename HType
, Type HEnum
, class T >
struct set_data_buffer_type_map_node {
typedef HType head_type
enum { head_enum = HEnum };
typedef T tail_type;
};
typedef
set_data_buffer_type_map_node< int , OCCIINT
set_data_buffer_type_map_node< float, OCCIBFLOAT
...
nil
> > // either count or keep adding these until compiler accepts :)
set_data_buffer_type_map;
template< typename T, class Map >
struct getter {
// recurse towards tail
Type get_enum() { return getter<T,typename Map::tail_type>::get_enum(); }
};
template< typename T, Type HEnum, class Tail >
struct getter< T, set_data_buffer_type_map<T,HEnum,Tail> > {
// current node has T as HType
Type get_enum() { return set_data_buffer_type_map<T,HEnum,Tail>::head_enum; }
};
template< typename T, typename HType, Type HEnum, >
struct getter< T, set_data_buffer_type_map<T,HEnum,nil> > {
// no function here, so compile-time error
};
template< typename T>
Type get_type_enum()
{
return getter<T, set_data_buffer_type_map>::get_enum();
}
(Note: This is just an outline. I have not even attempted to compile it. )
I will suggest to go with enum option. Using it as template means your API users should have idea about all the types before which can be bit difficult. Using it as enum also give them as option to refer the enum and decide which SQL types suits the requirement.
I'm toying around with the LLVM C++ API. I'd like to JIT compile code and run it.
However, I need to call a C++ method from said JIT-compiled code. Normally, LLVM treats method calls as function calls with the object pointer passed as the first argument, so calling shouldn't be a problem. The real problem is to get that function into LLVM.
As far as I can see, it's possible to use external linkage for functions and get it by its name. Problem is, since it's a C++ method, its name is going to be mangled, so I don't think it's a good idea to go that way.
Making the FunctionType object is easy enough. But from there, how can I inform LLVM of my method and get a Function object for it?
The dudes from the LLVM mailing list were helpful enough to provide a better solution. They didn't say how to get the pointer from the method to the function, but I've already figured out this part so it's okay.
EDIT A clean way to do this is simply to wrap your method into a function:
int Foo_Bar(Foo* foo)
{
return foo->bar();
}
Then use Foo_Bar's address instead of trying to get Foo::bar's. Use llvm::ExecutionEngine::addGlobalMapping to add the mapping as shown below.
As usual, the simplest solution has some interesting benefits. For instance, it works with virtual functions without a hiccup. (But it's so much less entertaining. The rest of the answer is kept for historical purposes, mainly because I had a lot of fun poking at the internals of my C++ runtime. Also note that it's non-portable.)
You'll need something along these lines to figure the address of a method (be warned, that's a dirty hack that probably will only be compatible with the Itanium ABI):
template<typename T>
const void* void_cast(const T& object)
{
union Retyper
{
const T object;
void* pointer;
Retyper(T obj) : object(obj) { }
};
return Retyper(object).pointer;
}
template<typename T, typename M>
const void* getMethodPointer(const T* object, M method) // will work for virtual methods
{
union MethodEntry
{
intptr_t offset;
void* function;
};
const MethodEntry* entry = static_cast<const MethodEntry*>(void_cast(&method));
if (entry->offset % sizeof(intptr_t) == 0) // looks like that's how the runtime guesses virtual from static
return getMethodPointer(method);
const void* const* const vtable = *reinterpret_cast<const void* const* const* const>(object);
return vtable[(entry->offset - 1) / sizeof(void*)];
}
template<typename M>
const void* getMethodPointer(M method) // will only work with non-virtual methods
{
union MethodEntry
{
intptr_t offset;
void* function;
};
return static_cast<const MethodEntry*>(void_cast(&method))->function;
}
Then use llvm::ExecutionEngine::addGlobalMapping to map a function to the address you've gotten. To call it, pass it your object as the first parameter, and the rest as usual. Here's a quick example.
class Foo
{
void Bar();
virtual void Baz();
};
class FooFoo : public Foo
{
virtual void Baz();
};
Foo* foo = new FooFoo;
const void* barMethodPointer = getMethodPointer(&Foo::Bar);
const void* bazMethodPointer = getMethodPointer(foo, &Foo::Baz); // will get FooFoo::Baz
llvm::ExecutionEngine* engine = llvm::EngineBuilder(module).Create();
llvm::Function* bar = llvm::Function::Create(/* function type */, Function::ExternalLinkage, "foo", module);
llvm::Function* baz = llvm::Function::Create(/* function type */, Function::ExternalLinkage, "baz", module);
engine->addGlobalMapping(bar, const_cast<void*>(barMethodPointer)); // LLVM always takes non-const pointers
engine->addGlobalMapping(baz, const_cast<void*>(bazMethodPointer));
One way is a C wrapper around the desired method, i.e.
extern "C" {
void wrapped_foo(bar *b, int arg1, int arg2) {
b->foo(arg1, arg2);
}
}
The extern "C" bit makes the function use C calling conventions and prevents any name mangling. See http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.6 for details on C/C++ interop including extern "C"
You should also probably be able to get the address of the function in your C++ code and then store that address in a global known to LLVM.
Huh, using the non-standard dladdr and a ridiculously convoluted and unsafe way to cast method pointers to void pointers, there seems to be a way to obtain the name of a method from its pointer.
This is certainly more dangerous than firearms. Don't do this at home (or at work, for that matter).
C++ forbids to cast method pointers to void* (which is required by dladdr to work) even with the almighty C cast, but you can cheat that.
#include <string>
#include <dlfcn.h>
template<typename T>
static void* voidify(T method)
{
asm ("movq %rdi, %rax"); // should work on x86_64 ABI compliant platforms
}
template<typename T>
const char* getMethodName(T method)
{
Dl_info info;
if (dladdr(voidify(method), &info))
return info.dli_sname;
return "";
}
From there:
int main()
{
std::cout << getMethodName(&Foo::bar) << std::endl;
// prints something like "_ZN3Foo3barEv"
}
...aaaand you should be able to use that symbol name with LLVM. But it won't work with virtual methods (another good reason to not use it).
EDIT Hacking much, much deeper into how virtual method pointers are handled, I've put together a more elaborate function that works for them, too. Only the most courageous of you should follow this link.