I am writing code in c++. I need to support few basic data types and something like BigInt. This types will be exposed to outside world(through header file), which might also include c program.
Should I implement BigInt like data type as struct or class?
The confusion is because
1. If I implement it as class, as OO advantages, I can do all processing in class. But I may have to implement some work around for c programs
2. If I implement it as struct I need not do anything special for c programs, but I loose modularity and ease of implementation.
basically C couldn't access C++ objects, either struct/class (they're the same in C++, only differs in default visibility specifier). You have to create procedural wrapper for the C++ object (i.e. creation, method call, destruction, etc).
For creation, create a function that returns opaque pointer (in C++, this would be the object pointer). For method call, add the returned pointer (from creation function above) as one of the (typically first) parameter. For destruction it's the same as method call, but typically receives no other parameter other than the pointer above.
If you plan on using it in C, I suggest you write it in C. C++ gets along with C a million times better than C gets along with C++. Another option would be to write it in C and then provide a thin C++ wrapper that gives it an OO interface.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Are there any available guidelines, habits, best practices... on how to expose a C++ library via C bindings (compiled as part of the library).
The objective is to not modify the C++ classes.
Assuming the following two C++ classes
class B {
public:
std::vector<int> list();
std::string toString();
};
class A {
public:
explicit A(size_t size);
B getB();
};
What would be the "best" way to expose these as a C API; a list of functions handling pointers and instantiating objects on the heap, callbacks ? Is there a list of generally accepted naming conventions ?
extern "C" {
A* A_new(size_t size);
void A_delete(A* a);
B* A_getB(A *a);
void B_delete(B* b);
...
}
(note: asking for generally accepted practices and conventions and/or tools is not asking for opinions but practical feedback)
My experience is that the basic question to answer is whether the C++ objects are singletons of some kind or if there will be multiple instances of these objects on the C side of the interface.
If they are singletons then the C interface can be a set of functions and all of the management, object handles, and other bits are held within the C++ side of the interface. The user of the library doesn't need to have any kind of a way to reference a particular C++ object.
However if there are multiple instances of the C++ objects then the decision as to how to handle these multiple objects and their lifetime has to be determined. The main two ways I have seen are (1) providing a pointer to the C++ object over to the C side of the interface or (2) providing a handle to the C++ object over to the C side of the interface with the handle referencing a management area on the C++ side.
I personally like the handle method because then modern C++ practices can be used for managing the lifetime of the objects. The objects are stored in some C++ container with a unique handle or identifier provided to the C interface and the C++ side owns the objects. The C side is requesting specific operations on the objects through the C interface.
The C interface may vary between being unique functions that map to the individual C++ object methods or being a more generic function that takes what amounts to a command flag by specifying a unique identifier for the C++ object method.
In the first alternative the methods of the C++ object are exposed as a C interface function which, in the case of multiple instances, takes either a pointer to the C++ object or the handle to the object. The C interface function, written in C++, then does the actual C++ object method call with the proper arguments. So this is just a C interface function that forwards the parameters to the C++ object.
In the second alternative, the C++ interface function has to determine, using a lookup table or a switch or something similar which method to invoke. Parameters may either be specified in the interface or variable arguments may be used. If variable arguments are used then you have the problem of parsing out the parameter list, marshaling the arguments, and then calling the C++ object method.
An additional consideration is the naming and namespace clutter. In C there is the traditional three letter prefix approach to naming of externals though in most cases more characters are more meaningful.
However the approach I really prefer is to have an external struct within which are function pointers to the C functions making up the interface. By doing this, you can name the struct something meaningful for your library and then you are free to name the actual function pointers however you like.
The actual C interface functions are static within the source file which exposes only the struct containing the function pointers. The struct itself is a global that is initialized when it is defined at the bottom of the source file containing the C interface functions.
What you're proposing is typically the best way to handle this. You have a function which return a pointer to a newly allocated object, a set of function that take that pointer and do various things, and one more that takes the pointer and frees the memory.
The only thing you need to add is a declaration for the type that is compatible with C:
typedef struct A A;
typedef struct A B;
You shouldn't expose std types in your C interface (public members in class B) because the C++ ABI is not standardized and you might end up with bugs that are very hard to figure out when the API consumer is using a different compiler version.
For example in your code I would rewrite B as follows:
class B {
public:
int* list(); // or write your own implementation for a vector type which you ship with the api
const char* toString();
};
Coming from Delphi, I'm used to using class references (metaclasses) like this:
type
TClass = class of TForm;
var
x: TClass;
f: TForm;
begin
x := TForm;
f := x.Create();
f.ShowModal();
f.Free;
end;
Actually, every class X derived from TObject have a method called ClassType that returns a TClass that can be used to create instances of X.
Is there anything like that in C++?
Metaclasses do not exist in C++. Part of why is because metaclasses require virtual constructors and most-derived-to-base creation order, which are two things C++ does not have, but Delphi does.
However, in C++Builder specifically, there is limited support for Delphi metaclasses. The C++ compiler has a __classid() and __typeinfo() extension for retrieving a Delphi-compatible TMetaClass* pointer for any class derived from TObject. That pointer can be passed as-is to Delphi code (you can use Delphi .pas files in a C++Builder project).
The TApplication::CreateForm() method is implemented in Delphi and has a TMetaClass* parameter in C++ (despite its name, it can actually instantiate any class that derives from TComponent, if you do not mind the TApplication object being assigned as the Owner), for example:
TForm *f;
Application->CreateForm(__classid(TForm), &f);
f->ShowModal();
delete f;
Or you can write your own custom Delphi code if you need more control over the constructor call:
unit CreateAFormUnit;
interface
uses
Classes, Forms;
function CreateAForm(AClass: TFormClass; AOwner: TComponent): TForm;
implementation
function CreateAForm(AClass: TFormClass; AOwner: TComponent): TForm;
begin
Result := AClass.Create(AOwner);
end;
end.
#include "CreateAFormUnit.hpp"
TForm *f = CreateAForm(__classid(TForm), SomeOwner);
f->ShowModal();
delete f;
Apparently modern Delphi supports metaclasses in much the same way as original Smalltalk.
There is nothing like that in C++.
One main problem with emulating that feature in C++, having run-time dynamic assignment of values that represent type, and being able to create instances from such values, is that in C++ it's necessary to statically know the constructors of a type in order to instantiate.
Probably you can achieve much of the same high-level goal by using C++ static polymorphism, which includes function overloading and the template mechanism, instead of extreme runtime polymorphism with metaclasses.
However, one way to emulate the effect with C++, is to use cloneable exemplar-objects, and/or almost the same idea, polymorphic object factory objects. The former is quite unusual, the latter can be encountered now and then (mostly the difference is where the parameterization occurs: with the examplar-object it's that object's state, while with the object factory it's arguments to the creation function). Personally I would stay away from that, because C++ is designed for static typing, and this idea is about cajoling C++ into emulating a language with very different characteristics and programming style etc.
Type information does not exist at runtime with C++. (Except when enabling RTTI but it is still different than what you need)
A common idiom is to create a virtual clone() method that obviously clones the object which is usually in some prototypical state. It is similar to a constructor, but the concrete type is resolved at runtime.
class Object
{
public:
virtual Object* clone() const = 0;
};
If you don't mind spending some time examining foreign sources, you can take a look at how a project does it: https://github.com/rheit/zdoom/blob/master/src/dobjtype.h (note: this is a quite big and evolving source port of Doom, so be advised even just reading will take quite some time). Look at PClass and related types. I don't know what is done here exactly, but from my limited knowledge they construct a structure with necessary metatable for each class and use some preprocessor magic in form of defines for readability (or something else). Their approach allows seamlessly create usual C++ classes, but adds support for PClass::FindClass("SomeClass") to get the class reference and use that as needed, for example to create an instance of the class. It also can check inheritance, create new classes on the fly and replace classes by others, i. e. you can replace CDoesntWorksUnderWinXP by CWorksEverywhere (as an example, they use it differently of course). I had a quick research back then, their approach isn't exceptional, it was explained on some sites but since I had only so much interest I don't remember details.
The problem is specific but the solution open ended. I'm a lone coder looking to bat some ideas around with some fellow programmers.
I have a wrapper for a maths library. The wrapper provides the system with a consistent interface, while allowing me to switch in/out math libraries for different platforms. The wrapper contains a single member, so say for my Matrix4x4 wrapper class there is an api_matrix_4x4 structure as the only member to the wrapper.
My current target platform has a nifty little optimised library, with a few of those nifty functions requiring a C-style array of the wrapper's embedded member, while my wrapper functions for those math API functions don't want to expose that member type to the rest of the system. So we have a collection of wrappers (reference/pointer to) going into the function, & the members of the wappers being needed in a collection inside the function, so they can be passed to the math API.
I'm predominantly using C++, including C++11 features, & can also go C-style. Ideally I want a no-exception solution, & to avoid as many, if not all dynamic allocations. My wrapper functions can use standard library arrays or vectors, or C-style pointers to arrays as parameters, & whatever is necessary internally, just no dynamic casting (Run-Time Type Information).
1) Can I cast a custom struct/class containing a single custom struct, to the custom struct? If so, what about if it was a standard library collection of them. I'm thinking about type slicing here.
2) Would you perhaps use a template to mask the type passed to the function, although the implementation can only act on a single type (based on the math API used), or is such usage of templates considered bad?
3) Can you think of a nifty solution, perhaps involving swaps/move semantics/emplacement? If so, please help by telling me about it.
4) Or am I resigned to the obvious, iterate through one collection, taking the member out into another, then using that for the API function?
Example of what I am doing by the wrapper struct & wrapper function signature, & example of what I am trying to avoid doing is given by the function implementation:
struct Vector3dWrapper
{
API_Specific_Vector_3d m_api_vector_3d;
inline void operation_needing_vector_3d_wrappers(std::vector<Vector3d>& vectors)
{
// Now need a collection of API_Specific_Vector_3ds
try
{
std::Vector<API_Specific_Vector_3d> api_vectors;
api_vectors.reserve(vectors.size());
for( auto vectors_itr = vectors.begin(); vectors_itr != vectors.end(); ++vectors)
{
// fill each Vector3d.m_api_vector_3d into api_vectors
}
}
catch(std::bad_alloc &e)
{
// handle... though in reality, try/catch is done elsewhere in the system.
}
// Signature is API_Multiply_Vectors_With_Matrix_And_Project(API_Specific_Vector_3d* vectors, size_t vector_count)
API_Multiply_Vectors_With_Matrix_And_Project(&api_vectors, api_vectors.size());
}
};
You can cast a standard-layout struct (such as a struct compatible with C) to its first member, but what's the point? Just access the first member and apply &.
Templates usually allow uniform parameterization over a set of types. You can write a template that's only instantiated once, but again that seems pointless. What you really want is a different interface library for each platform. Perhaps templates could help define common code shared between them. Or you could do the same in plain C by setting typedefs before #include.
Solution to what? The default copy and move semantics should work for flat, C-style structs containing numbers. As for deep copies, if the underlying libraries have pointer-based structures, you need to be careful and implement all the semantics you'll need. Safe… simple… default… "nifty" sounds dirty.
Not sure I understand what you're doing with collections. You mean that every function requires its parameters to be first inserted into a generic container object? Constructing containers sounds expensive. Your functions should parallel the functions in the underlying libraries as well as possible.
I want to create a Java wrapper against some third-party library with C interface. The library operates on a complex Context entity which is essentially a C++ object (C++ is used internally in that library, but API is in pure C). It would be natural to wrap this entity into a class accessible from Java. For that, a pointer to Context should be stored somewhere.
I see two options to do this:
to declare a new member on java side (as long, for example) and convert it to pointer type inside JNI methods implementation
to declare a new member in JNI header (That might be illegal if Java relies on the size of structure it gerenated for me by javah)
All the tutorials on JNI are too simple to give me a hint on how to wrap a complex entities with Java classes, any links on more verbose documentation are appreciated.
I also want to know where it is appropriate to call Context destruction function (C++ destructor inside) I don't want to use Java finalize for that as Java don't favor finalize methods and I supect there is a way to define a destruction procedure on native side.
I was reading the GoF book and in the beginning of the prototype section I read this:
This benefit applies primarily to
languages like C++ that don't treat
classes as first class objects.
I've never used C++ but I do have a pretty good understanding of OO programming, yet, this doesn't really make any sense to me. Can anyone out there elaborate on this (I have used\use: C, Python, Java, SQL if that helps.)
For a class to be a first class object, the language needs to support doing things like allowing functions to take classes (not instances) as parameters, be able to hold classes in containers, and be able to return classes from functions.
For an example of a language with first class classes, consider Java. Any object is an instance of its class. That class is itself an instance of java.lang.Class.
For everybody else, heres the full quote:
"Reduced subclassing. Factory Method
(107) often produces a hierarchy of
Creator classes that parallels the
product class hierarchy. The Prototype
pattern lets you clone a prototype
instead of asking a factory method to
make a new object. Hence you don't
need a Creator class hierarchy at all.
This benefit applies primarily to
languages like C++ that don't treat
classes as first-class objects.
Languages that do, like Smalltalk and
Objective C, derive less benefit,
since you can always use a class
object as a creator. Class objects
already act like prototypes in these
languages." - GoF, page 120.
As Steve puts it,
I found it subtle in so much as one
might have understood it as implying
that /instances/ of classes are not
treated a first class objects in C++.
If the same words used by GoF appeared
in a less formal setting, they may
well have intended /instances/ rather
than classes. The distinction may not
seem subtle to /you/. /I/, however,
did have to give it some thought.
I do believe the distinction is
important. If I'm not mistaken, there
is no requirement than a compiled C++
program preserve any artifact by which
the class from which an object is
created could be reconstructed. IOW,
to use Java terminology, there is no
/Class/ object.
In Java, every class is an object in and of itself, derived from java.lang.Class, that lets you access information about that class, its methods etc. from within the program. C++ isn't like that; classes (as opposed to objects thereof) aren't really accessible at runtime. There's a facility called RTTI (Run-time Type Information) that lets you do some things along those lines, but it's pretty limited and I believe has performance costs.
You've used python, which is a language with first-class classes. You can pass a class to a function, store it in a list, etc. In the example below, the function new_instance() returns a new instance of the class it is passed.
class Klass1:
pass
class Klass2:
pass
def new_instance(k):
return k()
instance_k1 = new_instance(Klass1)
instance_k2 = new_instance(Klass2)
print type(instance_k1), instance_k1.__class__
print type(instance_k2), instance_k2.__class__
C# and Java programs can be aware of their own classes because both .NET and Java runtimes provide reflection, which, in general, lets a program have information about its own structure (in both .NET and Java, this structure happens to be in terms of classes).
There's no way you can afford reflection without relying upon a runtime environment, because a program cannot be self-aware by itself*. But if the execution of your program is managed by a runtime, then the program can have information about itself from the runtime. Since C++ is compiled to native, unmanaged code, there's no way you can afford reflection in C++**.
...
* Well, there's no reason why a program couldn't read its own machine code and "try to make conclusions" about itself. But I think that's something nobody would like to do.
** Not strictly accurate. Using horrible macro-based hacks, you can achieve something similar to reflection as long as your class hierarchy has a single root. MFC is an example of this.
Template metaprogramming has offered C++ more ways to play with classes, but to be honest I don't think the current system allows the full range of operations people may want to do (mainly, there is no standard way to discover all the methods available to a class or object). That's not an oversight, it is by design.