How to Marshall C++ Native Objects to Managed C++ CLI - visual-c++

I have bunch of native C++ objects and classes contains DTL maps, maps of maps and lists and vectors.
I need to call managed C++ functions from C++ native code and need to pass these native objects and STL containers(lists,maps , maps of maps) to C++/CLI. It needs to marshal or some how serialize these objects. How can I do that with out any problem. So that After marshalling and serializing back to managed C++/CLI , maps should marshalled with dictionaries and dictionaries of dictionaries, stl list with managed List<> and so on..
how can I achieve this for all cases? Is it requires complex handling of marshalling issues...?
Regards
Usman

STL memory layout is implementation specific. E.g. sizeof(std::vector) is 16 in release and 20 in debug mode when you use the implementation comes with Visual C++. And you have pointers in STL classes that can't be marshaled meaningfully to managed memory. You can switch to platform-independent C or COM types in the interface (e.g. pass an array with a count parameter or a safe array) if you want to do marshaling as .Net has better understanding on these types. I recommend COM because it has richer types and support other languages in case you need it.
Alternatively if you need speed you can write a marshal_as template function to do the conversion so you can reuse the marshaling code or even the marshaling buffer, or write a managed wrapper for your C++ objects.
If the data being marshaled is too large to fit in the memory you can also serialize the data to temp file or database and read them back from managed code in chunks.

Related

How to use QStringView with QML?

I am trying to understand how/if I can use QStringView in signal/slots that are called from QML. For example, in the below code, can I use QStringView instead of QString?
Q_PROPERTY(QString priority READ priority WRITE setPriority NOTIFY priorityChanged)
From what I am reading from the documentation, any type that is supported by QVariant can be used in a Q_PROPERTY, I can understand why QStringView is not supported by QVariant but I am looking for a way to use QStringView with QML, instead of passing QString copies between the two all the time.
The supported conversions between QML and C++ data types are described in this document.
The supported data types could be split into four categories:
Basic datatypes
QObject derived classes (ex. QAbstractItemModel)
Some basic lists
Enumerations
Answer:QStringView is not part of any of these categories. So, it is not possible to transfer it to QML.
Possible workaround: You could try to create a QObject based wrapper around QStringView, which implements the desired QML interface.

MSVC2017 static runtime heap

I have A.dll and B.dll that links MSVC2017 runtime statically. Do they have separate heaps or share the same heap when they are loaded to the same exe module?
Can I pass std::string with the default allocator, for example, from A.dll to B.dll by value?
Each has their own separate heap manager. I expect passing std::string by value to end badly.
In general, since C++ doesn't define ABI, it's unwise to use C++ classes in general, and standard library classes in particular, in a DLL's public interface. One exception is when a) all modules (EXE and DLLs) link to the DLL runtime, and b) they are all built together, using the same version of the same compiler (at which point, there's little benefit in splitting into multiple modules in the first place).
There are two common approaches to designing DLL interface:
C-style free functions using only fundamental types, and structs and arrays thereof. Windows API is mostly like that.
Pointers to abstract classes with no data members and all methods pure virtual - also known as interfaces. At this point, you are using COM, or something substantially COM-like.
In either case, the program must arrange that all resources allocated by a DLL are deallocated in the same DLL. E.g. the DLL may require the caller to pass in buffers for the DLL to fill, so it doesn't return allocated memory; or provide a function the caller must use to deallocate memory allocated by the DLL; or use OS facilities such as CoTaskMemAlloc et al, and document this use.

How do I use nested Vecs with wasm-bindgen?

It doesn't appear that nested Vecs work with wasm-bindgen. Is that correct?
My goal is to have a Game of Life grid in Rust that I can return as rows, rather than a 1D Vec which requires the JavaScript to handle the indexing. Two workarounds I've thought of are:
Implement a sort of custom "iterator" in Rust, which is a method which returns the rows one-by-one.
Hand a 1D array to JavaScript but write a wrapper in JavaScript which handles the indexing and exposes some sort of an iterator to the consumer.
I hesitate to use either of these because I want this library to be usable by JavaScript and native Rust, and I don't think either would be very idiomatic in pure Rust land. Any other suggestions?
You're correct that wasm-bindgen today doesn't support returning types like Vec<Vec<u8>>.
A good rule of thumb for WebAssembly is that big chunks of data (like vectors) should always live in the same location to avoid losing too much performance. This means that you might want to explore an interface where a JS object wraps a pointer into WASM memory, and all of its methods work with row/column indices but modify WASM memory to keep it as the source of truth.
If that doesn't work out, then the best way to implement this today is either of the strategies you mentioned as well, although both of those require some level of JS glue code to be written as well.

How to expose a native enum to Java through JNI?

I am importing headers from an existing project for a port to Android-NDK. In a few cases, there are enums defined in the native headers which I would like to use from the Java layer. How can one go about doing that?
Ideally, I'd like to just expose the constants to the Java layer somehow, but I don't see a way to do that.
The most obvious possibility is to doubly-define the enums in both Java and C++. However, the existing headers a) have no explicit numbering, b) have elements which are #ifdef'ed, and c) are shared with existing projects through SVN Externals. Therefore, doubly-defining the enums seems substantially more brittle than even the typical case.
The next idea is to use some build-time code-gen to create the enum in Java based on the pre-processed header -- possibly just as integer constants rather than a Java enum?
The third and most-nebulous idea I have is to define the enum in Java, pass those objects to the JNI glue, and have it compare against the some invocation of FindClass(), GetStaticFieldID(), and GetStaticObjectField(); then have the JNI glue re-map those to the native enum. That all seems inefficient, though.
Suggestions?
I would make a completely independent set of Java enums, and map between them at the JNI level where you have both available. Make sure to run javah on the enum classes so you get some #defines for their ordinals.

String^ declaration in C++

As far as I am aware C++ string declaration follows the form:
std::string param;
I was walking through a code and realised the declaration of string is done this way:
System::String^ param;
Can anyone share light on this declaration?! Is this Microsoft Visual C++ string declaration or a special library which provides another alternative to using C++ string.
It's Microsoft-specific, and is part of a language they call C++/CLI. This syntax declares a Common Language Runtime (CLR) String variable (the same kind you get when you declare a string in C#). These are not directly interchangeable with the several C/C++ string types, but Microsoft provides marshalling facilities to convert CLR String objects to unmanaged strings and vice versa.
C++/CLI enables developers to create programs that bridge regular C++ classes/functions (otherwise called "unmanaged code") with CLR classes/functions (otherwise called "managed code"). Microsoft also exposes lower-level features of the CLR to C++/CLI, some that are exposed to C# too (like pointers), and some that aren't (like finer granularity over member access levels).
It's useful if you want to use an existing C or C++ library in a language like C# (by making the bindings in C++/CLI then exposing them to the CLR without going through P/Invokes), or if you want to port an existing unmanaged C/C++ library or application to a managed environment.
This is C++/CLI syntax for a handle to an object on the managed heap.

Resources