LuaBind bindings for c standard library? - c++

I've begun running into slight issues with certain functions that I've bound to lua using luabind. These functions return or take std:string objects as arguments, and the data that c++ eventually gets is garbage, apparently because lua doesn't recognize the datatype. I'm fine with manually binding std:: classes over as I need them, but I have to wonder if that's already been done for the c standard library anywhere. I can't seem to find any sort of bindings library; does anyone know if such a project exists?

Luabind already has automatic conversions between Lua strings and std::string (as well as char*). So you should be able to use them as parameters and/or return values just fine. If you are unable to do so, then something is going wrong, either on your side or on Luabind's side.
Luabind also has an adapter to convert a return type that conforms to an STL-style container into a Lua iterator function. Thus, you can use it in a for-loop like this:
for object in CppFuncThatReturnsStdVector() do
--Do something with "object"
end
Other than these, I am not aware of any particular effort to make a Luabind library that directly exposes the standard C++ library to Lua. It probably wouldn't be a good idea anyway; Lua tables cover most of the needs you might have for STL-style containers. And most of the other stuff are things Lua can handle with its own standard library.

Related

Can I use Eigen3 from Rust? [duplicate]

I want to call a C++ dynamic library (*.so) from Rust, but I don't want to build it from Rust. Like this,
cc::Build::new()
    .file("src/foo.cc")
.shared_flag(true)
.compile("libfoo.so");
In some cases, I only need to call several functions, not all the functions. How can I use it?
Before you go further, make sure you have a basic idea of Rust FFI (foreign function interface).
In Rust, it's easy to call C, but hard to call C++.
To call C functions in Rust, you just have to wrap them with extern, do some basic type casting and sometimes unsafe.
To call C++ functions, since Rust does not have built-in knowledge of C++ features, you may have to do a lot of manual translation. For example, here is part of the documentation from Rust-Qt:
Many things are directly translated from C++ to Rust:
Primitive types are mapped to Rust's primitive types (like bool) and types provided by libc crate (like libc::c_int).
Fixed-size numeric types (e.g int8_t or qint8) are mapped to Rust's fixed size types (e.g. i8).
Pointers, references and values are mapped to Rust's respective types.
C++ namespaces are mapped to Rust submodules.
C++ classes and structs are mapped to Rust structs. This also applies to all instantiations of template classes encountered in the
library's API, including template classes of dependencies.
Free functions are mapped to free functions.
Class methods are mapped to structs' implementations.
Destructors are mapped to Drop and CppDeletable implementations.
Function pointer types are mapped to Rust's equivalent representation. Function pointers with references or class values are
not supported.
static_cast and dynamic_cast are available in Rust through corresponding traits.
Names of Rust identifiers are modified according to Rust's naming
conventions.
When direct translation is not possible:
Contents of each include file of the C++ library are placed into a separate submodule.
Method overloading is emulated with wrapping arguments in a tuple and creating a trait describing tuples acceptable by each method.
Methods with default arguments are treated in the same way.
Single inheritance is translated to Deref and DerefMut implementation, allowing to call base class methods on derived
objects. When deref coercions are not enough, static_cast should be
used to convert from derived to base class.
Getter and setter methods are created for each public class field.
Not implemented yet but planned:
Translate C++ typedefs to Rust type aliases.
Implement operator traits for structs based on C++ operator methods (issue). Operators
are currently exposed as regular functions with op_ prefix.
Implement Debug and Display traits for structs if applicable methods exist on C++ side.
Implement iterator traits for collections.
Subclassing API (issue).
Provide access to a class's public variables (issue).
Provide conversion from enums to int and back (used in Qt API).
Support C++ types nested into template types, like Class1<T>::Class2.
Not planned to support:
Advanced template usage, like types with integer template arguments.
Template partial specializations.
Template methods and functions.
My suggestion is to wrap your C++ library as a C library, then call it the official FFI way, or use rust-bindgen to automatically do the wrapping.
If you still want to call C++ in Rust, rustcxx seems like a handy tool.
As to the library linking, it's pretty simple:
Put the library into your system library searching paths like /usr/lib or /usr/local/lib/, make sure it can be found by ldconfig -p.
Or use the environment variable LD_LIBRARY_PATH to specify the path where your library lays when you run cargo from the CLI.
According to Rust's official website, there is no official support for linkage with C++. Instead you can try and use C libraries.
There is also a thread on this issue in their users forum, where users suggest some 3rd party projects aiming to tackle this issue:
bindgen - Auto generation of FFI for Rust
cpp-to-rust - Allows to use C++ libraries from Rust. The main target of this project is Qt.
I didn't use them, so I can't recommend anything particular or share my experience, but good luck :)
I feel it's worth mentioning as of now there is CXX library in crate
https://docs.rs/cxx/latest/cxx/
https://cxx.rs/
This is what I will be using going forward in order to interoperate with a C++ Library from a vendor.
The assigned answer has a link but it's publicly archived and all active work is likely here :
https://github.com/dtolnay/cxx

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.

How to call a C++ dynamic library from Rust?

I want to call a C++ dynamic library (*.so) from Rust, but I don't want to build it from Rust. Like this,
cc::Build::new()
    .file("src/foo.cc")
.shared_flag(true)
.compile("libfoo.so");
In some cases, I only need to call several functions, not all the functions. How can I use it?
Before you go further, make sure you have a basic idea of Rust FFI (foreign function interface).
In Rust, it's easy to call C, but hard to call C++.
To call C functions in Rust, you just have to wrap them with extern, do some basic type casting and sometimes unsafe.
To call C++ functions, since Rust does not have built-in knowledge of C++ features, you may have to do a lot of manual translation. For example, here is part of the documentation from Rust-Qt:
Many things are directly translated from C++ to Rust:
Primitive types are mapped to Rust's primitive types (like bool) and types provided by libc crate (like libc::c_int).
Fixed-size numeric types (e.g int8_t or qint8) are mapped to Rust's fixed size types (e.g. i8).
Pointers, references and values are mapped to Rust's respective types.
C++ namespaces are mapped to Rust submodules.
C++ classes and structs are mapped to Rust structs. This also applies to all instantiations of template classes encountered in the
library's API, including template classes of dependencies.
Free functions are mapped to free functions.
Class methods are mapped to structs' implementations.
Destructors are mapped to Drop and CppDeletable implementations.
Function pointer types are mapped to Rust's equivalent representation. Function pointers with references or class values are
not supported.
static_cast and dynamic_cast are available in Rust through corresponding traits.
Names of Rust identifiers are modified according to Rust's naming
conventions.
When direct translation is not possible:
Contents of each include file of the C++ library are placed into a separate submodule.
Method overloading is emulated with wrapping arguments in a tuple and creating a trait describing tuples acceptable by each method.
Methods with default arguments are treated in the same way.
Single inheritance is translated to Deref and DerefMut implementation, allowing to call base class methods on derived
objects. When deref coercions are not enough, static_cast should be
used to convert from derived to base class.
Getter and setter methods are created for each public class field.
Not implemented yet but planned:
Translate C++ typedefs to Rust type aliases.
Implement operator traits for structs based on C++ operator methods (issue). Operators
are currently exposed as regular functions with op_ prefix.
Implement Debug and Display traits for structs if applicable methods exist on C++ side.
Implement iterator traits for collections.
Subclassing API (issue).
Provide access to a class's public variables (issue).
Provide conversion from enums to int and back (used in Qt API).
Support C++ types nested into template types, like Class1<T>::Class2.
Not planned to support:
Advanced template usage, like types with integer template arguments.
Template partial specializations.
Template methods and functions.
My suggestion is to wrap your C++ library as a C library, then call it the official FFI way, or use rust-bindgen to automatically do the wrapping.
If you still want to call C++ in Rust, rustcxx seems like a handy tool.
As to the library linking, it's pretty simple:
Put the library into your system library searching paths like /usr/lib or /usr/local/lib/, make sure it can be found by ldconfig -p.
Or use the environment variable LD_LIBRARY_PATH to specify the path where your library lays when you run cargo from the CLI.
According to Rust's official website, there is no official support for linkage with C++. Instead you can try and use C libraries.
There is also a thread on this issue in their users forum, where users suggest some 3rd party projects aiming to tackle this issue:
bindgen - Auto generation of FFI for Rust
cpp-to-rust - Allows to use C++ libraries from Rust. The main target of this project is Qt.
I didn't use them, so I can't recommend anything particular or share my experience, but good luck :)
I feel it's worth mentioning as of now there is CXX library in crate
https://docs.rs/cxx/latest/cxx/
https://cxx.rs/
This is what I will be using going forward in order to interoperate with a C++ Library from a vendor.
The assigned answer has a link but it's publicly archived and all active work is likely here :
https://github.com/dtolnay/cxx

Safely use containers in C++ library interface

When designing a C++ library, I read it is bad practice to include standard library containers like std::vector in the public interface (see e.g. Implications of using std::vector in a dll exported function).
What if I want to expose a function that takes or returns a list of objects? I could use a simple array, but then I would have to add a count parameter, which makes the interface more cumbersome and less safe. Also it wouldn't help much if I wanted to use a map, for example. I guess libraries like Qt define their own containers which are safe to export, but I'd rather not add Qt as a dependency, and I don't want to roll my own containers.
What's the best practice to deal with containers in the library interface? Is there maybe a tiny container implementation (preferably just one or two files I can drop in, with a permissive license) that I can use as "glue"? Or is there even a way to make std::vector etc. safe across .DLL/.so boundaries and with different compilers?
You can implement a template function. This has two advantages:
It lets your users decide what sorts of containers they want to use with your interface.
It frees you from having to worry about ABI compatibility, because there is no code in your library, it will be instantiated when the user invokes the function.
For example, put this in your header file:
template <typename Iterator>
void foo(Iterator begin, Iterator end)
{
for (Iterator it = begin; it != end; ++it)
bar(*it); // a function in your library, whose ABI doesn't depend on any container
}
Then your users can invoke foo with any container type, even ones they invented that you don't know about.
One downside is that you'll need to expose the implementation code, at least for foo.
Edit: you also said you might want to return a container. Consider alternatives like a callback function, as in the gold old days in C:
typedef bool(*Callback)(int value, void* userData);
void getElements(Callback cb, void* userData) // implementation in .cpp file, not header
{
for (int value : internalContainer)
if (!cb(value, userData))
break;
}
That's a pretty old school "C" way, but it gives you a stable interface and is pretty usable by basically any caller (even actual C code with minor changes). The two quirks are the void* userData to let the user jam some context in there (say if they want to invoke a member function) and the bool return type to let the callback tell you to stop. You can make the callback a lot fancier with std::function or whatever, but that might defeat some of your other goals.
Actually this is not only true for STL containers but applies to pretty much any C++ type (in particular also all other standard library types).
Since the ABI is not standardized you can run into all kinds of trouble. Usually you have to provide separate binaries for each supported compiler version to make it work. The only way to get a truly portable DLL is to stick with a plain C interface. This usually leads to something like COM, since you have to ensure that all allocations and matching deallocations happen in the same module and that no details of the actual object layout are exposed to the user.
TL;DR There is no issue if you distribute either the source code or compiled binaries for the various supported sets of (ABI + Standard Library implementation).
In general, the latter is seen as cumbersome (with reasons), thus the guideline.
I trust hand-waving guidelines about as far as I can throw them... and I encourage you to do the same.
This guidelines originates from an issue with ABI compatibility: the ABI is a complex set of specifications that defines the exact interface of a compiled library. It is includes notably:
the memory layout of structures
the name mangling of functions
the calling conventions of functions
the handling of exception, runtime type information, ...
...
For more details, check for example the Itanium ABI. Contrary to C which has a very simple ABI, C++ has a much more complicated surface area... and therefore many different ABIs were created for it.
On top of ABI compatibility, there is also an issue with Standard Library Implementation. Most compilers come with their own implementation of the Standard Library, and these implementations are incompatible with each others (they do not, for example, represent a std::vector the same way, even though all implement the same interface and guarantees).
As a result, a compiled binary (executable or library) may only be mixed and matched with another compiled binary if both were compiled against the same ABI and with compatible versions of a Standard Library implementation.
Cheers: no issue if you distribute source code and let the client compile.
If you are using C++11, you can use cppcomponents. https://github.com/jbandela/cppcomponents
This will allow you to use among other things std::vector as a parameter or return value across Dll/or .so files created using different compilers or standard libraries. Take a look at my answer to a similar question for an example Passing reference to STL vector over dll boundary
Note for the example, you need to add a CPPCOMPONENTS_REGISTER(ImplementFiles) after the CPPCOMPONENTS_DEFINE_FACTORY() statement

Passing a Python array to a C++ vector using Swig

I have an array of objects in Python
[obj1, obj2, obj3]
and I want to pass them to off to a C++ function to perform some computation. I'm using SWIG to write my interface. The class type of the passed object is already defined in C++.
What's the best way to do this?
It depends on if your function is already written and cannot be changed, in which case you may need to check Swig docs to see if there is already a typemap from PyList to std::vector (I think there is). If not, taking PyObject* as the argument to the function and using the Python C API for manipulating lists should work fine. I haven't had any problems with it so far. For self-documentation, I recommend typedef'ing PyObject* to some kind of expected type, like "PythonList" so that the parameters have some meaning.
This may also be useful:
How to expose std::vector<int> as a Python list using SWIG?