Creating interface for c++ dll - c++

I have a class that is constructed with a path to a text file. It parses the text file and stores a lot of data in various vectors and maps as its members. I'd like to share the class as a dll with users of different versions of MSVS (something that's new to me).
My original implementation when it was just for me returned the STL containers directly. After reading, my understanding is that this is dangerous because different compilers or different versions of the same compiler can easily implement the containers differently. One solution I saw was to explicitly instantiate any templates you were using and export them as well. I also had strings so I'd need to instantiate and export that since a std::string is actually an alias for a more complex template. However, even if I went that route it appears there's nothing I can do about exporting maps.
What I've done now is that instead of giving the user access to the containers, I have accessor functions that take an index (or a key for the maps, or a key and index for a vector of maps I've got) and fetch the value. All my parameters and return values are primitive types, including const char* for the strings.
Am I understanding the problem correctly, and is this a reasonable approach to it? Do I need to worry about the integral primitives in c++ not being strictly defined in the standard? I suppose I could use the std-defined integral types as well. One issue is that the user won't be able to iterate over the containers or check size. I could provide the size as a member(all the vectors are the same size), and then I guess it'd just be up to the user to provide their own vector and fill it if they want the other vector functionality.

Related

C++ Array of different functions

It's easy to do something like that in Python, but implementing it in C++ seems to be more challenging.
I actually have some solution to this, but I'd like to see if you can see any better solution.
Here's what I want to do.
I have a list of values of different types (string, integer, can be also instance of some class etc.). Now here's the first problem - in C++ (unlike in Python) all values in vector/array have to be of the same type.
The solution I can see is that I can use std::any like this: vector<std::any> list.
I also have an array/vector of functions (or pointers to functions) with different parameter types and returned values - one function can accept string and integer and return a char and other can accept a char and return an int. Here's another problem: in C++ you can have an array/vector of functions only if they have the same parameters and returned values (as far as I know) because in your declaration of the vector you need to define the parameter types and the returned value.
The other problem is that I need to retrieve the information about the parameters and the returned value for each function. In other words, having those functions, I need to know that this function accepts 2 strings and 1 integer and returns a char for example. In Python I can use inspect.signature function to retrieve information about type annotations of a function. In C++, I don't know if there is a way to do this.
The solution I can see here is to use std::any again (although I will use another solution, I will explain why later).
The solution I can see to this problem is that I won't retrieve that information but instead the user of the class which accepts this vector of functions will simply have to specify what are the parameter types and returned value for each function. In other words, the solution I can see is that I won't be retrieving the information about parameter types programmatically.
The other problem I have is that later I need to call one of those functions with some parameters. In Python I do this like this:
arguments = [1, 'str', some_object] // here I prepare a list of arguments (they are of different types)
func(**arguments)
In C++ I can do unpacking as well, but not if the parameters are of different types.
The solution I can see here is as follows. Those functions in the vector will all accepts only argument which is vector<std::any> args which will simply contain all of the arguments. Later when I want to call the function, I will simply construct a vector with std::any values and pass it as an argument. This would also solve the previous problem of not being able to store vector of functions with different parameters.
Can you see better solutions?
You might wonder what I need all of this is for. I do some program synthesis stuff and I need to programmatically construct programs from existing functions. I'm writing a library and I want the user of my library to be able to specify those base functions out of which I construct programs. In order to do what I want, I need to know what are the parameters and returned values of those functions and I need to call them later.
I believe what you are looking for is std::apply. You can use std::tuple instead of std::vector to store a list of values of different types -- as long as the types are known at compile-time. Then std::apply(f, t) in C++ is basically the same as f(*t) in Python.
I have a list of values of different types (string, integer, can be also instance of some class etc.).
A type which is a union of subtypes is called a sum type or tagged union. C++ has the template std::variant for that.
Now here's the first problem - in C++ (unlike in Python) all values in vector/array have to be of the same type.
Of course, so use cleverly C++ containers. You might want some std::map or std::vector of your particular instance of std::variant.
I also have an array/vector of functions
You probably want some std::vector of std::function-s and code with C++ lambda expressions
You should read a good C++ programming book
I'm writing a library and I want the user of my library to be able to specify those base functions out of which I construct programs.
You could get inspiration from SWIG and consider generating some C++ code in your library. So write (in Python or C++) your C++ metaprogram (generating some C++ code, like ANTLR does) which generates the user code, and your user would adapt his build automation tool for such a need (like users of GNU bison do).
You might also consider embedding Guile (or Lua) in your application.
PS. You might be interested by other programming languages like Ocaml, Go, Scheme (with Guile, and read SICP), Common Lisp (with SBCL), or Rust.

Method operating on container: hardcode the container type, or use generic template iterators?

I have code where, conceptually, my input is some container of Foo objects. The code "processes" these objects one by one, and the desired result is to fill up a container of FooProduct result objects.
I only need a single pass through the input container. The "processing" is stateful (this isn't an std::transform()) and the number of result objects is independent of the number of input objects.
Offhand, I could see two obvious ways to define the API here.
The easiest way to do this is to hardcode a specific type of container. For example, I could decide I'm expecting vector parameters, e.g.:
void ProcessContainerOfFoos(const std::vector<Foo>& in, std::vector<FooProduct>&out);
But, I don't really have any reason to limit client code to a particular type of container. Instead of constraining the parameter types specifically to vector, I could make the method generic and use iterators as template parameters:
/**
* #tparam Foo_InputIterator_T An input iterator giving objects of type Foo.
* #tparam FooProduct_OutputIterator_T An output iterator writing objects
* of type FooProduct.
*/
template<typename Foo_InputIterator_T, typename FooProduct_OutputIterator_T >
void ProcessContainerOfFoos(Foo_InputIterator_T first, Foo_InputIterator_T last,
FooProduct_OutputIterator_T out);
I'm debating between these two formulations.
Considerations
To me, the first code seems to me to be "easier" and the second seems "more correct":
Non-template types make the signature clearer; I don't need to explain in the documentation what types to use and what the constraints on the template parameter are.
Without templates I can hide the implementation in the .cpp file; with templates I'll need to expose the implementation in a header file, forcing client code to include anything I need for the actual processing logic.
The templated version feels like it expresses my intention more clearly, because I'd rather be indifferent to what container type is used.
The templated version is more flexible and testable - for example, in my code I might be using some custom data structure MySuperEfficientVector , but I'd still be able to test MyFooProcessor without any dependency on the custom class.
Beyond subjective choice given these considerations, is there a major reason to choose one of these over the other? Likewise, is there a better way to construct this API which I'm missing?
Besides the considerations that you've already listed:
The template version allows the client code to pass any iterator
range, for example a sub-range or reverse iterators, not just an entire container from begin to end.
The template version allows passing value types other than Foo. For this to be useful, the processing must be generic of course.
If the template works with only specific value type and the user tries to use iterators to wrong type, the error message might not be very descriptive of their mistake. If this is a concern, you can give the user a better error using type traits: static_assert(std::is_same<Iter::value_type, Foo>::value, "I want my Foo"); Until concepts proposal is added to the standard, there is no good way to communicate the requirements of a template type in the signature to the user.
There is also the option to provide both functions. The hard coded one can delegate to the templated version. This gives you the advantages of both versions at the expense of bloating your api.
It depends. If this function is going to be used with vectors for the time beeing why bother?
I suggest doing templated version only when it becomes necessary. Predicting such things in advance is hard.

practice and discovery of Boost Type Erasure

I am reading about boost type erasure and I am trying to figure out the potential usage. I would like to practice it a bit while I am reading tons of documentations about the topic (it looks a big one). The most quoted area of application that is networking / exchanging data between client and server.
Can you suggest some other example or exercise where I can play I bit with this library?
Type Erasure is useful in an extraordinary amount of situations, to the point where it may actually be thought of as a fundamentally missing language feature that bridges generic and object oriented programming styles.
When we define a class in C++, what we are really defining is both a very specific type and a very specific interface, and that these two things do not necessarily need to be related. A type deals with the data, where as the interface deals with transformations on that data. Generic code, such as in the STL, doesn't care about type, it cares about interface: you can sort anything container or container-like sequence using std::sort, as long as it provides comparison and iterator interface.
Unfortunately, generic code in C++ requires compile time polymorphism: templates. This doesn't help with things which cannot be known until runtime, or things which require a uniform interface.
A simple example is this: how do you store a number of different types in a single container? The simplest mechanism would be to store all of the types in a void*, perhaps with some type information to distinguish them. Another way is to recognize all of these types have the same interface: retrieval. If we could make a single interface for retrieval, then specialize it for each type, then it would be as if part of the type had been erased.
any_iterator is another very useful reason to do this: if you need to iterate over a number of different containers with the same interface, you will need to erase the type of the container out of the type of the iterator. boost::any_range is a subtle enhancement of this, extending it from iterators to ranges, but the basic idea is the same.
In short, any time you need to go from multiple types with a similar interface to a single type with a single interface, you will need some form of type erasure. It is the runtime technique that equates compile time templates.

memcpy and std components like map: runtime failer

I have an old C library I try to modify. There is a line like:
memcpy(&m_agents[idx].params, params, sizeof(dtCrowdAgentParams));
And ofcourse C stule pod like values and structs get copied. But I tried to add to params.some_struct.some_inner_map_field std::map and it does not get initialised on memcpy.
So I wonder how to copy my map keeping it alive? (if possible not extending methods of params and params.some_struct)
I would need to see the full definition of the struct to be sure, but this should work:
m_agents[idx].params = *params;
For POD types, it will do the same thing as memcpy. For non-POD types, it will call their assignment operator.
Replacing it with
m_agents[idx].params = *params;
will correct that instance. However, it's reasonable to suppose that the C library you are working with is assuming POD throughout and so you will need to check the whole codebase to ensure it's not doing anything that will break things elsewhere.
Are your maps mutable within the library or can you treat them as constant while the library is handling the data? If you can treat them as constant consider passing a handle, or pointer, to you map into the library instead of including the map itself in the parameter struct.

unique type identifiers across different C++ programs

Is there a way to automatically (i.e. not by hand) assign unique identifiers to types in different programs that share common source code? I'd need one program to tell another "use type X" and the other would know what that "X" meant. Of course, they would (partially) share the source code, as you cannot construct types in runtime, I just want an automatic way of constructing a map from some sort of identifiers (integers or strings) to e.g. factory functions returning objects of given type.
An obvious choice I'd go for is result of name() in std::type_info, but as I understand, that is not even guaranteed to be different across types, and using address of std::type_info instances is certainly not going to work across programs.
I cannot use C++11, but can use Boost for this.
I just want an automatic way of constructing a map from some sort of
identifiers (integers or strings) to e.g. factory functions returning
objects of given type.
Not going to happen, not within Standard C++, anyway.
You could take a look at boost serialisation. It automatically generates unique ids for polimorphic classes and allows the explicit registration of non polimorphic ones.