C++ How do I instantiate a VkSubProcess object from this header? - c++

I'm having a hard time understanding how to instantiate a ViewKit VkSubProcess object. Manpage for this thing is here: VkSubProcess.3
I have read up enough about C++ to understand that this header describes a reference counted abstract base class and I think I more-or-less understand the concepts involved. However, my feeble attempts at actually using this thing have been unsuccessful.
My efforts lead to various compiler errors like:
"The class "RPtr_VkSubProcessRep" has no member "create"
or:
"No instance of constructor 'VkSubProcessRep::VkSubProcessRep' matches the argument list"
Could somebody be kind enough to please show how to instantiate a VkSubProcess object from this header?
For brevity I've removed from the header the functions mentioned in the manpage that come into play only after the instance has been created.
Many thanks.
#ifndef _VKPROCESS_H
#define _VKPROCESS_H
#include <signal.h>
#include <Xm/Xm.h>
#include <Vk/VkCallbackObject.h>
#include <Vk/VkBase.h>
#include <Vk/VkApp.h>
class VkSPCounted : public VkCallbackObject {
friend class VkSPRPtr_base;
int nreferences;
void addRef() { nreferences++; }
void delRef() {
if (--nreferences <= 0)
delete this;
}
public:
VkSPCounted() : VkCallbackObject() { nreferences = 0; }
virtual ~VkSPCounted();
private:
VkSPCounted(const VkSPCounted&);
VkSPCounted &operator= (const VkSPCounted&);
};
class VkSPRPtr_base : public VkBase {
public:
operator void*() { return (void *)ptr; }
VkSPRPtr_base& operator=(VkSPCounted *tp) {
if (ptr) ptr->delRef();
ptr = tp;
if (ptr) ptr->addRef();
return *this;
}
VkSPRPtr_base& operator=(const VkSPRPtr_base& r){
if (ptr) ptr->delRef();
ptr = r.ptr;
if (ptr) ptr->addRef();
return *this;
}
protected:
VkSPCounted *ptr;
VkSPRPtr_base() : VkBase() { ptr = 0; }
VkSPRPtr_base(const VkSPRPtr_base& r) : VkBase() {
ptr = r.ptr;
if (ptr) ptr->addRef();
}
VkSPRPtr_base(VkSPCounted *tp) : VkBase() {
ptr = tp;
if (ptr) ptr->addRef();
}
~VkSPRPtr_base() {
if (ptr) ptr->delRef();
}
};
class VkSubProcessRep;
class RPtr_VkSubProcessRep : public VkSPRPtr_base {
public:
RPtr_VkSubProcessRep();
RPtr_VkSubProcessRep(VkSubProcessRep *tp);
RPtr_VkSubProcessRep(const RPtr_VkSubProcessRep& that) : VkSPRPtr_base(that) {}
~RPtr_VkSubProcessRep();
RPtr_VkSubProcessRep& operator=(VkSubProcessRep *tp) {
*((VkSPRPtr_base *) this) = (VkSPCounted *) tp;
return *this;
}
VkSubProcessRep& operator *();
VkSubProcessRep *operator->();
int operator !(){ return !ptr; }
};
typedef RPtr_VkSubProcessRep VkSubProcess;
class VkSubProcessRep : public VkSPCounted {
public:
static VkSubProcess create(char* cmd,
int killChildOnExit,
int redirectIn);
/* Actually create VkSubProcess */
void run();
protected:
VkSubProcessRep(const char* prog,
char **argv,
int killChildOnExit,
int redirectIn);
~VkSubProcessRep();
private:
VkSubProcessRep(const VkSubProcessRep&);
VkSubProcessRep &operator= (const VkSubProcessRep&);
};
#endif

Well, after spending the day reading up on C++, I now know that this header describes a Reference-counted Singleton pattern. From what I have read, the static 'create()' function and the protected constructor seem to be typical for this pattern.
You might use it like so:
VkSubProcess process = VkSubProcessRep::create("ls -al", 1, 1);
process->run();

Related

Create a transparent wrapper class in C++ for a C-style object

I want to implement a class in C++ whose purpose is implementing RAII mechanism for a C-style object.
Then, I need to be able to pass an instance of this class to all the C-style functions that receive the mentioned C-style object as argument. I know that this should be solved with unique_ptr, but I cannot use C++11 for now. Anyway, I would like to understand how this should be made, regardless that there are better solutions.
I have several doubts regarding to which operators I must overload, and the difference beteween some of them.
Below is an example of code with the implementation I have made. I am specially confused with the operators 1 and 2 (what is the difference?)
I want to know if the code I have implemented covers all the use cases, I mean, all the scenarios where the C library could use the object. In addition, I would like to understand the difference between the operators 1 and 2.
C-Style object
// Example: a C-style library called "clib" which use an object called "cobj":
struct cobj {
int n;
};
void clib_create_cobj(struct cobj **obj) {
*obj = (struct cobj*)malloc(sizeof(cobj));
(*obj)->n = 25;
}
void clib_release_cobj(struct cobj *obj) {
free(obj);
}
void clib_doSomething(struct cobj *obj) {
std::cout << obj->n << std::endl;
}
C++ "transparent" wrapper
// My wrapper class for implementing RAII
class CobjWrapper {
public:
CobjWrapper(struct cobj *obj) : m_obj (obj) { }
~CobjWrapper() {
if(m_obj != NULL) {
clib_release_cobj(m_obj);
m_obj = NULL;
}
}
operator struct cobj* () const { // (1)
return m_obj;
}
struct cobj& operator * () { // (2)
return *m_obj;
}
struct cobj** operator & () { // (3)
return &m_obj;
}
struct cobj* operator->() { // (4)
return m_obj;
}
private:
struct cobj *m_obj;
};
The main method
// The main method:
int main() {
struct cobj *obj = NULL;
clib_create_cobj(&obj);
CobjWrapper w(obj);
clib_doSomething(w);
return 0;
}
The above source can be tested here:
http://cpp.sh/8nue3
The following is an implicit cast
operator struct cobj* () const { // (1)
with example usage
CobjWrapper wrapper = /**/;
struct cobj* obj = wrapper;
whereas the following is the unary operator *
struct cobj& operator * () { // (2)
with example usage
CobjWrapper wrapper = /**/;
struct cobj& obj = *wrapper;
BTW, I would completely hide the C struct, something like:
class CobjWrapper {
struct ObjDeleter
{
void operator()(cobj *obj) const { clib_release_cobj(obj); }
};
public:
CobjWrapper()
{
cobj *obj = nullptr;
clib_create_cobj(&obj);
m_obj.reset(obj);
}
void doSomething() { clib_doSomething(m_obj.get()); }
private:
std::unique_ptr<cobj, ObjDeleter> m_obj;
};

Extend auto_ptr to release a C-style object

I want to implement a RAII mechanism for a net-snmp C library struct snmp_pdu object.
That object is created with a method called struct snmp_pdu* snmp_pdu_create(int type) and released with a method void snmp_free_pdu(struct snmp_pdu *obj).
What I have done is extend auto_ptr to call the method libname_free_obj in the destructor. Below is the code:
class auto_snmp_pdu : public std::auto_ptr<snmp_pdu>
{
public:
virtual ~auto_snmp_pdu()
{
snmp_free_pdu(get());
}
};
Is the above correect?
EDIT
I cannot use unique_ptr since I am using an old version of g++ and I am not authorized to update it.
auto_ptr is deprecated and bug-prone. Use unique_ptr with a custom deleter. Here is one implementation:
#include <memory>
extern "C" {
struct snmp_pdu;
struct snmp_pdu* snmp_pdu_create(int type);
void snmp_free_pdu(struct snmp_pdu *obj);
}
struct snmp_pdu_deleter
{
void operator()(snmp_pdu* p) const noexcept {
snmp_free_pdu(p);
}
};
using snmp_pdu_ptr = std::unique_ptr<snmp_pdu, snmp_pdu_deleter>;
snmp_pdu_ptr create_snmp_pdu(int x) {
return snmp_pdu_ptr(snmp_pdu_create(x));
}
int main()
{
auto ptr = create_snmp_pdu(0);
}
but my compiler is pre-c++11
unique_ptr and move semantics are fairly easy to simulate:
#include <utility>
#include <iostream>
#include <stdlib.h>
extern "C" {
struct snmp_pdu {};
void foo(snmp_pdu*) { std::cout << "foo" << std::endl; }
struct snmp_pdu* snmp_pdu_create(int type) {
return (snmp_pdu*)malloc(sizeof(snmp_pdu));
}
void snmp_free_pdu(struct snmp_pdu *obj) {
free(obj);
}
}
struct snmp_pdu_proxy
{
struct mover {
mover(snmp_pdu*& impl_ref) : impl_ref_(impl_ref) {}
snmp_pdu*& impl_ref_;
};
snmp_pdu_proxy(int code)
: impl_(snmp_pdu_create(code))
{}
snmp_pdu_proxy(mover m)
: impl_(0)
{
std::swap(impl_, m.impl_ref_);
}
mover move() {
return mover ( impl_ );
}
snmp_pdu_proxy& operator=(mover m)
{
snmp_pdu_proxy tmp = move();
std::swap(m.impl_ref_, impl_);
return *this;
}
operator snmp_pdu* () const {
return impl_;
}
~snmp_pdu_proxy() {
if(impl_) {
snmp_free_pdu(impl_);
}
}
private:
snmp_pdu_proxy& operator=(const snmp_pdu_proxy&);
snmp_pdu* impl_;
};
int main()
{
snmp_pdu_proxy ptr = snmp_pdu_proxy(0);
snmp_pdu_proxy p2 = ptr.move();
ptr = p2.move();
foo(ptr);
}
If you're using C++03, then you can't use unique_ptr for sure. However, this doesn't justify using auto_ptr. It's a horrible construct and is semantically full of problems. For example, it's copyable, and a copy operation moves the object under it. I can't even start to describe how many problems that will cause.
Just create your own class that will do the deallocation for you with RAII. It's much simpler than you think. Here are a few examples:
On my blog I described a few ways to do this, even with C++03.
This is a SmartHandle class that deallocates anything (unfortunately it's C++11). I use it for HDF5. You can change it to fit C++03 with a functor.
This is a shared_ptr implementation that supports detaching/releasing an object (it's not thread-safe). I created this for a project that works with gcc 4.3.
Take a look at these, and you'll get the idea. You can modify these examples to match your needs.
Good luck!

C++/CLI template wrapper round

I have a set of multiple C++ classes that have the same interface (not derived from each other though). I'm trying to wrap these to make them available in .NET.
I currently have a method that defines the wrapper class using C/C++ #defines and then I can subsequently instantiate classes with a simple line of code
However I can't debug this. Ideally I would like to be able to use a generic or a template. However I can't use a C++ type inside a generic which would be the ultimate way to solve this problem.
Has anyone any idea of how I can do this without using the dreaded macros?
EDIT:
OK Here is an example of the templated class I have written:
template< typename CPPResamplerClass >
ref class TResampler
{
CPPResamplerClass* pResampler;
public:
TResampler( int inputSampleRate, int outputSampleRate, int bufferLen ) :
pResampler( new CPPResamplerClass( inputSampleRate, outputSampleRate, bufferLen ) )
{
}
~TResampler()
{
this->!ResamplerName();
}
!TResampler()
{
if (pResampler)
{
delete pResampler;
pResampler = nullptr;
}
}
property int HistorySize
{
int get()
{
return pResampler->HistorySize();
}
}
array< float >^ ResampleAudio(array< float >^ in)
{
pResampler->Get
array< float >^ out = gcnew array< float >(in->Length);
cli::pin_ptr< float > pIn = &in[0];
cli::pin_ptr< float > pOut = &out[0];
unsigned int inLen = in->Length;
unsigned int outLen = out->Length;
if (pResampler->ResampleAudio(pOut, outLen, pIn, inLen))
{
System::Array::Resize(out, outLen);
return out;
}
return nullptr;
}
};
typedef TResampler< ::Vec::SpeexResample > SpeexResample;
I then want to access this from C# however SpeexResample does not exist. This could well be because I am using a typedef ...
Templates don't exist until they're instantiated. While you could instantiate one explicitly:
template ref class TResampler<SomeNativeClass>;
It wouldn't be exactly user-friendly to use from C#. The exported type will literally have angle brackets in its name. Good luck using that. In C# it's only doable through reflection.
The next best thing is to use derived types. Here's a minimal example:
#include "stdafx.h"
#include <iostream>
namespace CppCli {
class NativeClassA
{
int foo;
public:
NativeClassA(int foo) : foo(foo) { std::cout << "Built native class A" << std::endl; }
int getFoo() const { return foo; }
};
class NativeClassB
{
int foo;
public:
NativeClassB(int foo) : foo(foo) { std::cout << "Built native class B" << std::endl; }
int getFoo() const { return foo; }
};
template<typename NativeClass>
public ref class ManagedWrapper
{
NativeClass* ptr;
public:
ManagedWrapper(int foo)
: ptr(new NativeClass(foo))
{}
~ManagedWrapper()
{
this->!ManagedWrapper();
}
!ManagedWrapper()
{
if (ptr)
{
delete ptr;
ptr = nullptr;
}
}
property int Foo { int get() { return ptr->getFoo(); } }
};
public ref class ManagedWrapperA : ManagedWrapper<NativeClassA>
{
public:
ManagedWrapperA(int foo) : ManagedWrapper(foo) {}
};
public ref class ManagedWrapperB : ManagedWrapper<NativeClassB>
{
public:
ManagedWrapperB(int foo) : ManagedWrapper(foo) {}
};
};
Sure enough, ManagedWrapperA and ManagedWrapperB are visible from C#. Maybe you could macro these definitions and still get a decent debugging experience.

Storage of function pointer in polymorphic class without explicit template specialization

I am trying to create a helper class to abstract invoking function pointers. With feedback from others on SO, I am using a polymorphic class to achieve this (shown below). Templates are also used to reduce code duplication.
typedef void(*PFNFOO1) (int);
typedef void(*PFNFOO2) (double);
typedef void(*PFNBAR1) (long);
typedef void(*PFNBAR2) (float);
typedef struct FOO_TABLE
{
PFNFOO1 pfnFoo1;
PFNFOO2 pfnFoo2;
} FOO_TABLE;
typedef struct BAR_TABLE
{
PFNBAR1 pfnBar1;
PFNBAR2 pfnBar2;
} BAR_TABLE;
enum TABLE_TYPE
{
TYPE_FOO = 0,
TYPE_BAR = 1,
};
template <typename T>
class FooBarImpl : public FooBarBase
{
public:
// GetFunc is created to centralize needed validation before function is invoked
void* GetFunc(size_t funcOffset)
{
// do some validation
return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
}
void* GetpfnFoo1() { return GetFunc(offsetof(T, pfnFoo1)); }
void* GetpfnFoo2() { return GetFunc(offsetof(T, pfnFoo2)); }
void* GetpfnBar1() { return GetFunc(offsetof(T, pfnBar1)); }
void* GetpfnBar2() { return GetFunc(offsetof(T, pfnBar2)); }
T* m_FooBarTable;
};
class FooBarBase
{
public:
static FooBarBase* CreateFooBar(TABLE_TYPE tableType)
{
switch(tableType)
{
case (TYPE_FOO) :
{
return new FooBarImpl<FOO_TABLE>();
}
break;
case (TYPE_BAR) :
{
return new FooBarImpl<BAR_TABLE>();
}
break;
}
}
virtual void* GetpfnFoo1() = 0;
virtual void* GetpfnFoo2() = 0;
virtual void* GetpfnBar1() = 0;
virtual void* GetpfnBar2() = 0;
};
int _tmain(int argc, _TCHAR* argv[])
{
{
FooBarBase *pFooBar = FooBarBase::CreateFooBar(TYPE_FOO);
// Initialize Foo table
auto p = reinterpret_cast<PFNFOO1>(pFooBar->GetpfnFoo1());
int parameter = 1;
p(parameter);
}
{
FooBarBase *pFooBar = FooBarBase::CreateFooBar(TYPE_FOO);
// Initialize Bar table
auto p = reinterpret_cast<PFNBAR2>(pFooBar->GetpfnBar2());
float parameter = 1.0f;
p(parameter);
}
return 0;
}
This is currently giving me complication errors as "C2039: 'pfnBar1' : is not a member of 'FOO_TABLE'" which makes sense because one of the implicit template specialization will try to do "offsetof(FOO_TABLE, pfnBar1)," which isn't allowed. I have two questions. First, I am wondering what's the best way to address this error. I think I can possibly address this by providing explicit template specializations for FooBarImpl and FooBarImpl, but I'd like to avoid doing that because it means that if I were to add a new table type later, I'd have to add another specialization. Also, it increases code duplication. Therefore, if there's a way to fix this issue without explicit template specialization, please let m know.
For my second question, if explicit template specialization cannot be avoided, I have also tried this:
class FooBarBase;
template <typename T>
class FooBarImpl : public FooBarBase
{
};
template <>
class FooBarImpl<FOO_TABLE> : public FooBarBase
{
public:
typedef FOO_TABLE T;
// GetFunc is created to centralize needed validation before function is invoked
void* GetFunc(size_t funcOffset)
{
// do some validation
return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
}
void* GetpfnFoo1() { return GetFunc(offsetof(T, pfnFoo1)); }
void* GetpfnFoo2() { return GetFunc(offsetof(T, pfnFoo2)); }
T* m_FooBarTable;
};
template<>
class FooBarImpl<BAR_TABLE> : public FooBarBase
{
public:
typedef BAR_TABLE T;
// GetFunc is created to centralize needed validation before function is invoked
void* GetFunc(size_t funcOffset)
{
// do some validation
return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
}
void* GetpfnBar1() { return GetFunc(offsetof(T, pfnBar1)); }
void* GetpfnBar2() { return GetFunc(offsetof(T, pfnBar2)); }
T* m_FooBarTable;
};
But for some reason, I keep getting this error "error C2504: 'FooBarBase' : base class undefined" even if it was working fine before I specialized the templates.
If anyone has ideas about these 2 questions, I'd really appreciate your feedback. Thanks.

How come a pointer to a derived class cannot be passed to a function expecting a reference to a pointer to the base class?

Sorry for the long title but I did want to be specific.
I expected the following code to work but it doesn't and I can't figure out why :/
#include <cstdio>
#include <cassert>
class UniquePointer
{
public:
void Dispose()
{
delete this;
}
friend void SafeDispose(UniquePointer*& p)
{
if (p != NULL)
{
p->Dispose();
p = NULL;
}
}
protected:
UniquePointer() { }
UniquePointer(const UniquePointer&) { }
virtual ~UniquePointer() { }
};
class Building : public UniquePointer
{
public:
Building()
: mType(0)
{}
void SetBuildingType(int type) { mType = type; }
int GetBuildingType() const { return mType; }
protected:
virtual ~Building() { }
int mType;
};
void Foo()
{
Building* b = new Building();
b->SetBuildingType(5);
int a = b->GetBuildingType();
SafeDispose(b); // error C2664: 'SafeDispose' : cannot convert parameter 1 from 'Building *' to 'UniquePointer *&'
b->Dispose();
}
int main(int argc, char* argv[])
{
Foo();
return 0;
}
Imagine it were legal. Then you could write code like this:
class Animal : public UniquePointer
{
};
void Transmogrify(UniquePointer*& p)
{
p = new Animal();
}
void Foo()
{
Building* b = nullptr;
Transmogrify(b);
b->SetBuildingType(0); // crash
}
Observe that you have violated the type system (you put an Animal where a Building should be) without requiring a cast or raising a compiler error.
I do not think that it is possible to make it work the way you have it designed. Instead, try the following:
template <typename T>
void SafeDispose(T * & p)
{
if (p != NULL)
{
p->Dispose();
p = NULL;
}
}
class UniquePointer
{
public:
void Dispose()
{
delete this;
}
protected:
UniquePointer() { }
UniquePointer(const UniquePointer&) { }
virtual ~UniquePointer() { }
};
It is not allowed because if it were you could do the following:
friend void SafeDispose(UniquePointer*& p)
{
p = new UniquePointer();
}
Building* building;
SafeDispose(building)
//building points to a UniquePointer not a Building.
I guess the work around would be a template function.
To answer the title of your question, you cannot bind a non-const reference to base to a derived class instance because you could then set that reference to a pointer to a base instance that isn't a derived. Consider this function:
void Renew(UniquePointer *& p) {
delete p;
p = new UniquePointer();
}
if you could pass it a pointer to Building you would be able to set it incorrectly to point to a UniquePointer instance.
As it has already been suggested the solution is to change your reference to a plain pointer. Not only this solves your problem, but it is also a better implementation of SafeDispose(); as you wrote it this function gave the false idea that you would always set to 0 all your UniquePointer instances. But what would happen if somebody wrote (assuming UniquePointer constructor was public for simplicity):
UniquePointer *p1 = new UniquePointer();
UniquePointer *p2 = p1;
SafeDispose(p1);
They would expect all of their UniquePointers to be properly taken care of, when p2 is actually invalid.
I guess your SafeDispose should probably look more like :
friend void SafeDispose(UniquePointer** p) ...
In order to invoke it using
SafeDispose(&(UniquePointer*)b);
Then it should work this way.
But your next statement
b->Dispose();
will break cause b should now be NULL, cause it has been disposed and set to NULL by your SafeDispose method.