What is the difference between gcnew and ref new - c++-cli

I just have stumbled upon ref new here and am wondering whether there is a difference to gcnew.
The code example here shows how a handle to an object on the managed heap is being created using ref new:
Foo^ spFoo = ref new Foo();
and using gcnew here
int ^ i = gcnew int(13);
So are they conceptually equivalent?

In case you are simply confused by the layout of the documentation:
C++/CLI is for the Common Language Runtime (CLR).
C++/CX is for the Windows Runtime (WinRT).
They are similar enough to be documented together but they are not the same.
That's why they have three headings in the documentation that you linked:
All Platforms
Windows Runtime
Common Language Runtime
For C++/CLI, gcnew is what you use. Unless you are using C++/CX, the "Windows Runtime" sections don't apply.

Related

C++ expected a type specifier (Visual Studio)

I have tried many things. please help me.....
Full Source Code:
Source Code
Troubled Code:
MySqlDataAdapter adapter;
DataTable table;
private: System::Void AcceptedApplications_Load(System::Object^ sender,
System::EventArgs^ e) {
MySqlCommand^ com = gcnew MySqlCommand("command", conn);
adapter = new MySqlAdapter(com);
}`
Standard warning: While it's certainly possible to write the main body of your application in C++/CLI, or even write the GUI in C++/CLI using WinForms, it is not recommended. C++/CLI is intended for interop scenarios: where C# or other .Net code needs to interface with unmanaged C++, C++/CLI can provide the translation between the two. Because of that, C++/CLI has all of the complexities of C++, all of the complexities of C#, and some complexities of its own. For primary development, it is recommended to use C# with either WinForms or WPF if you want managed code, or C++ with MFC if you want unmanaged.
MySqlDataAdapter adapter;
...
adapter = new MySqlAdapter(com);
A couple issues:
It looks like you forgot the word "Data" when creating the object.
According to MySQL's reference site, that's a managed class. Therefore, it should have a ^ at the declaration and gcnew when instantiated.
public ref class types generally need the ^ in C++/cli and gcnew.
MySqlDataAdapter^ adapter = gcnew MySqlDataAdapter();
DataTable^ table = gcnew DataTable();

C++/CLI - XML based active reports

This is in continuation to one of my previous queries(active reports in C /CLI). I am accessing an xml-based active report from a C++/CLI application. Is there any way by which I can have a data communication with the active report from C++/CLI, for example, I want to print the managed data present in the C++/CLI application on the details section of the XML report which the application accesses. I don't want to use any c# code. Can it be done? Thanks.
Sure, ActiveReports can do it. Since C++/CLI produces standard .NET objects you can create objects in C++/CLI and ActiveReports will bind to them. Create an IEnumerable collection of objects that you want to bind to (each object in the collection is like a database "row").
Take a look at the examples at Binding Reports to a Data Source. Expand the code sections under the heading To use the IEnumerable data source and you'll see how to do it in C#. You would do precisely the same thing in C++/CLI, you'll just change the syntax from C# to C++/CLI. Clearly, you know C++/CLI syntax so you can do that part, but I think this answers your question regarding how to do this with ActiveReports.
Update based on question asked in comments:
You should be able to handle an ActiveReports' event such as the FetchData event using something like the following code:
void MyFetchDataHandler(Object^ sender, FetchEventArgs^ eArgs)
{
//put handling code here...
}
myReport->FetchData += ref new FetchEventHandler(this, &MyClass::MyFetchDataHandler)
I didn't compile this (I don't have AR handy), but it should be close. Please see Microsoft's reference documentation on C++/CLI event syntax here.

Mixed management in C++

I have added a class to my program and tested it. I was really surprised that there was any real errors. Here is the code:
#pragma once
#include "Iingredient.h"
#include <string>
#include <vector>
using namespace std;
ref class Recipe{
private:
string partsName;
vector<Iingredient> ing;
public:
Recipe(){}
};
And here are the errors:
Error 23 error C4368: cannot define 'partsName' as a member of managed
'Recipe': mixed types are not
supported c:\users\user\documents\visual studio
2010\projects\smestras2_l1\Recipe.h 10 1 file2_L1
Error 24 error C4368: cannot define 'ing' as a member of managed
'Recipe': mixed types are not
supported c:\users\user\documents\visual studio
2010\projects\smestras2_l1\Recipe.h 11 1 file2_L1
I googled a bit and found out that its about managed and unmanaged code.
How to fix this? Is it related with manged and unmanaged code or not? if so how?
I agree with others: you shouldn't use C++/CLI in most circumstances, you should use C# (or another "normal" managed language) for that (assuming you want to write a .Net application). C++/CLI is useful mostly in special circumstances, like interoperating between managed and unmanaged code.
If you're sure you want use C++/CLI, you can't put native classes into managed ones. But you can put pointers to native classes there:
ref class Recipe{
private:
string* partsName;
vector<Iingredient>* ing;
};
The code above works. But you have to keep in mind that those are normal native C++ pointers and that means you have to manually delete them. To do that property, you should read about how destructors and finalizers work in C++/CLI.
When defining ref class Recipe, you made it managed. But std::string and std::vector are umanaged types. You are trying to declare native variables in managed class, but it is not allowed.
Seems, you are novice in C++. Just, don't use C++/CLI. Consider C#, if you target .Net or unmanaged C++.
You cannot use unmanaged types in a managed class, ref keyword, because the heap and the managed heap are two different types of memory. To solve this specific problem you can use a managed string type (System::String^). The carrot tells the compiler that the type is a handle to a managed class.
Another way of going about this problem is to use pointers, that way the pointer will be on the managed heap, and the actual memory for that object will be in the standard unmanaged heap, which is where Recipe is located.
To construct your Recipe class you would have to do
Recipe^ recipe = gcnew Recipe();
With no idea of c++-cli, I can try and guess that the problem is that you are defining a reference type and trying to use C++ types inside (a std::string field) rather than whatever the equivalent managed type is (String?).
The reason why this can be problematic is that it mixes resource management approaches. Reference types are intended to be used out of a garbage collector, and unless you implement a destructor or IDisposable will just be ignored once proven that the last reference is lost. On the other hand, to be able to manage the memory in the internal field the std::string destructor must be called.

Copy constructor and assignment operator in CLI

I'm trying to locate examples of assignment operators and copy constructors in C++/CLI. I have spent a lot of time on Google and surprisingly I can't find a decent example of something that seems pretty common.
.NET semantics have no such thing as a copy constructor or assignment operator. You can define one in your ref classes, but it will be used only in the C++ side if you request explicitly a copy` For value classes, everything is builtin and you cannot override copy semantics.
Example:
public ref class Foo
{
Foo(const Foo% f);
};
Foo^ f = gcnew Foo;
Foo^ g = gcnew Foo(*f); // This will call C++ copy constructor. No .NET equivalent.
Look at ICloneable if you want to implement deep copy semantics in the .NET style.
Also look there to get the different copy behaviors you can have. I'd strongly advice against storing ref classes on the stack though.

export typedefs in .NET dlls

I've written a wrapper for a C++ dll in C++/CLI. Inside the wrapper, I made some typedefs. Is there a way to export these names as .NET classes?
Background: the typedef'd classes are some templates. For these templates to work, you need a managed and a native parameter (this is part of the translation). This is impossible for the client of the wrapper to program / know. That's why he needs the different aliases for the used versions of the template.
I exchanged the typedefs with some new class definitions that derive from the template. This should work.
I do not have too much information but typedefing should work only on Clr types. Generic classes, maybe but template classes can not ne typedefed. Also among native types, only the ones that are common (the word "common" may not be correct here.) to .net i.e. double, int, char, Char* (not char*) etc.
This code works and introduces a "new" type to clr.
namespace example
{
#ifdef _WIN64
typedef sizeT UInt64
#else
typedef sizeT UInt32
#endif
}
Now you have size_t of .Net, whose size depends on platform.