Managed C++ ^ (handle) --> What is it and how does it relate to references and pointers - managed-c++

What is the difference between a handle to an object in Managed C++
such as:
System::String^ str = gcnew System::String();
and the ordinary C++ pointers?
Also how do they relate to references we have in C#?

You are not talking about (the older) Managed C++, but about C++/CLI, right?
In C#, your code is equivalent to
System.String str=new System.String();
In C++/CLI, a handle to an object is just the same as a reference in C# - you have reference counting, garbage collector etc.
Ordinary C++ pointers, on the other hand, are (in most cases) pointers to unmanaged objects. You can (of course) have C++ pointers to managed objects, just the way you have pointers available in C# (in unsafe code). Look here for a detailed explanation of pointers in C#, and here for some details about pointers in C++/CLI. Those pointers are not handled by the garbage collector.

Related

Advice on implementing a garbage collector in Rust

I'm working on a toy programming JavaScript-like language which I'm writing in Rust, and this language has a very basic mark and sweep garbage collector. I have a working prototype, and the way I implemented it is to wrap Rust objects which are going to be allocated on the GC heap inside of a Box. Then I can get a pointer to the GC'd object and wrap pointer into a dynamically-typed Value type, i.e.:
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Value
{
Int64(i64),
UInt64(u64),
HostFn(HostFn),
Fun(*mut Function),
Str(*mut String),
Nil,
}
These are the values which my bytecode interpreter works with. The full source code is here if anyone wants to see more about how the GC works and provide feedback. I'm trying to keep the implementation as simple as possible so that this will be beginner-friendly.
What I would like advice with is that working with mutable pointers like this in Rust is very unergonomic. Every time I want to dereference them, I have to wrap everything in unsafe. This means, if I want to implement string concatenation or equality, I have to wrap the whole thing in an unsafe block where I'll dereference and borrow both strings. I have to do the same thing if I want to implement function calls. That's going to result in unsafe blocks everywhere in the implementation of my interpreter.
So my question is: can we make this more ergonomic somehow? One potential idea would be to have a helper method on Value that can return a &'static mut String for example. This is essentially lying to the Rust compiler about lifetimes for the sake of convenience, because the programmer still needs to be careful that GC'd values are on the VM heap, otherwise they will be collected. Would this be safe though? The real danger would come if the Rust compiler were to reorder operations around. Advice welcome.

export Qt function to Tcl

What is the best way to export the code written in Qt to the script language TCL. In the code Qt, I use the data structure in Qt like QMAP, QLIST other than those in STL, so the SWIG may not recognize them and neither some other macros in Qt.
You need a linking function with this signature:
extern "C" int theFunctionName(ClientData clientData, Tcl_Interp *interp,
int argc, char **argv)
which you register with Tcl_CreateCommand. (Or there's Tcl_CreateObjCommand, which uses a more efficient type management system, but in principle it's pretty similar.) This is what SWIG would construct for you, with lots of guidance, but it's not too hard to DIY and you'll probably end up with a better interface anyway. (SWIG's handling of enumerations and bit-sets is usually very unidiomatic from a Tcl perspective.)
That linking function has to decide the values in argv to create the values that are passed to your Qt/C++ code, and then it uses Tcl_SetResult or Tcl_SetObjResult to store the result back in the Tcl_Interp context before returning TCL_OK or TCL_ERROR (for success or an exception).
I guess a QMap would look like a Tcl dictionary, and a QList like a Tcl list, but the details could get quite tricky. The details depend on exactly what's going on (stuff like callbacks gets a little tricky, especially in threaded code!)

Converting from String^ to String*

I'm currently having a small issue which i thought would be easy, but not, so,(maybe it is easy, but i don't know) i need to convert a String^ into a String^* so basically a string pointer, small snippet of code:
ARPLC_command_byuser = textBox1->Text;
I've already tried various of methods, but all seem to fail(well, they don't, i do).
If you have any idea, please tell me what to do.
That's not possible. A managed object is moved around in memory when the garbage collector compacts the heap. Which will invalidate any pointer. This is the primary reason that C++/CLI uses the ^ hat to indicate object references, they are pointers under the hood that the garbage collector can recognize and update when the object is moved.
Technically it is possible to pin a managed object to ensure that it doesn't get moved. Something you can do with pin_ptr<> or GCHandle::Alloc(). This should be avoided. Convert the managed string to a native pointer by copying it into unmanaged memory using the Marshal class.

Linux Function Interception for OpenCL

I'm fairly new to C so be gentle.
I want to use the library interception method for Linux to replace calls to the OpenCL library with my own library. I understand that this can be done using LD_PRELOAD. So I can just re-implement the OpenCL functions as defined in the OpenCL header file within my own library which can then be linked against.
The problem is that this OpenCL header also contains some extern struct definitions, e.g.
typedef struct _cl_mem * cl_mem;
which are not defined within the OpenCL header. Is it possible these structs are defined within the OpenCL shared lib? If not, where might they be defined?
Cheers
Chris
That typedef declares a type pointing to a struct, the contents of which are undeclared. This means code using it can't do things like checking its size, copying the struct, or inspecting its contents - it simply has no idea what size it is.
This is a traditional technique in C to create an opaque, or private, type. You can declare the struct inside your OpenCL library, and the official header puts no restrictions on what that struct contains. It could even be empty, if all you need is an ID you can store in the pointer itself, though this is rarely done.
An example of the same technique used in the standard C library is the FILE type. It might be as simple as an integer file descriptor, or as complex as a struct containing the entire filesystem state; standard C code won't know. The particulars are known to the library only.
In short, you can declare that struct however you like - as long as you implement every function that handles that struct. The program that links to your library never handles the struct, only pointers to it.

Execution speed of references vs pointers

I recently read a discussion regarding whether managed languages are slower (or faster) than native languages (specifically C# vs C++). One person that contributed to the discussion said that the JIT compilers of managed languages would be able to make optimizations regarding references that simply isn't possible in languages that use pointers.
What I'd like to know is what kind of optimizations that are possible on references and not on pointers?
Note that the discussion was about execution speed, not memory usage.
In C++ there are two advantages of references related to optimization aspects:
A reference is constant (refers to the same variable for its whole lifetime)
Because of this it is easier for the compiler to infer which names refer to the same underlying variables - thus creating optimization opportunities. There is no guarantee that the compiler will do better with references, but it might...
A reference is assumed to refer to something (there is no null reference)
A reference that "refers to nothing" (equivalent to the NULL pointer) can be created, but this is not as easy as creating a NULL pointer. Because of this the check of the reference for NULL can be omitted.
However, none of these advantages carry over directly to managed languages, so I don't see the relevance of that in the context of your discussion topic.
There are some benefits of JIT compilation mentioned in Wikipedia:
JIT code generally offers far better performance than interpreters. In addition, it can in some or many cases offer better performance than static compilation, as many optimizations are only feasible at run-time:
The compilation can be optimized to the targeted CPU and the operating system model where the application runs. For example JIT can choose SSE2 CPU instructions when it detects that the CPU supports them. With a static compiler one must write two versions of the code, possibly using inline assembly.
The system is able to collect statistics about how the program is actually running in the environment it is in, and it can rearrange and recompile for optimum performance. However, some static compilers can also take profile information as input.
The system can do global code optimizations (e.g. inlining of library functions) without losing the advantages of dynamic linking and without the overheads inherent to static compilers and linkers. Specifically, when doing global inline substitutions, a static compiler must insert run-time checks and ensure that a virtual call would occur if the actual class of the object overrides the inlined method.
Although this is possible with statically compiled garbage collected languages, a bytecode system can more easily rearrange memory for better cache utilization.
I can't think of something related directly to the use of references instead of pointers.
In general speak, references make it possible to refer to the same object from different places.
A 'Pointer' is the name of a mechanism to implement references. C++, Pascal, C... have pointers, C++ offers another mechanism (with slightly other use cases) called 'Reference', but essentially these are all implementations of the general referencing concept.
So there is no reason why references are by definition faster/slower than pointers.
The real difference is in using a JIT or a classic 'up front' compiler: the JIT can data take into account that aren't available for the up front compiler. It has nothing to do with the implementation of the concept 'reference'.
Other answers are right.
I would only add that any optimization won't make a hoot of difference unless it is in code where the program counter actually spends much time, like in tight loops that don't contain function calls (such as comparing strings).
An object reference in a managed framework is very different from a passed reference in C++. To understand what makes them special, imagine how the following scenario would be handled, at the machine level, without garbage-collected object references: Method "Foo" returns a string, which is stored into various collections and passed to different pieces of code. Once nothing needs the string any more, it should be possible to reclaim all memory used in storing it, but it's unclear what piece of code will be the last one to use the string.
In a non-GC system, every collection either needs to have its own copy of the string, or else needs to hold something containing a pointer to a shared object which holds the characters in the string. In the latter situation, the shared object needs to somehow know when the last pointer to it gets eliminated. There are a variety of ways this can be handled, but an essential common aspect of all of them is that shared objects need to be notified when pointers to them are copied or destroyed. Such notification requires work.
In a GC system by contrast, programs are decorated with metadata to say which registers or parts of a stack frame will be used at any given time to hold rooted object references. When a garbage collection cycle occurs, the garbage collector will have to parse this data, identify and preserve all live objects, and nuke everything else. At all other times, however, the processor can copy, replace, shuffle, or destroy references in any pattern or sequence it likes, without having to notify any of the objects involved. Note that when using pointer-use notifications in a multi-processor system, if different threads might copy or destroy references to the same object, synchronization code will be required to make the necessary notification thread-safe. By contrast, in a GC system, each processor may change reference variables at any time without having to synchronize its actions with any other processor.

Resources