|
I am migrating a C++ application to .NET.
In C++ ,I have an template class which uses some ATL library classes
for eg.
template< class T >
class MyBaseClass:
public IConnectionPointContainerImpl<t>,
public IPersistStorageImpl<t>,
public IPersistPropertyBagImpl<t>,
{
}
Now i need to use this call in my new C# .net project where my new .NET call will get derive from above MyBaseClass .
Please let me know how can i archive this ???
Is this possible to use a template class which uses some ATL libraray classes directly in C# ?
`chiman
|
|
|
|
|
There is no straightforward method to use template classes in other CLI languages like C#. This is because of the difference in how C++ templates and CLI generics works. C++ templates will be instantiated at compile time and CLI generics will be on runtime. C++/CLI also supports managed templates, but unfortunately it is not portable to other CLI languages.
If you want to use inheritance, you may need to create managed classes that calls the template class for each known type. Like MyBaseClassInt which use MyBaseClass<int> etc. This will not be the correct method as you will have class explosion when you have several types to be used.
Prefer composition over inheritance. In such case, this can be easily solved by providing a factory class which checks the type and instantiates respective template instance. Any new types can be easily added to the factory method without recompiling the whole application. We are taking the capability of C++/CLI to mix generic and template type parameters. To see how this can be done, consider the following code:
template< class T >
class MyBaseClass:
public IConnectionPointContainerImpl,
public IPersistStorageImpl,
public IPersistPropertyBagImpl,
{
public:
void DoSomething();
};
generic<typename T>
public interface class IManagedBase
{
public:
void DoSomething();
};
template<typename T>
ref class MyBaseClassWrapper : IManagedBase<T>
{
public:
virtual void DoSomething()
{
MyBaseClass<T> native;
native.DoSomething();
}
};
public ref class NativeObjectBuilder
{
public:
generic<typename T> virtual IManagedBase<T> GetBaseObject()
{
if(T::typeid == int::typeid)
return (IManagedBase<T>^) gcnew MyBaseClassWrapper<int>();
else if(T::typeid == double::typeid)
return (IManagedBase<T>^) gcnew MyBaseClassWrapper<double>();
}
}; From C#, you can use it like
NativeObjectBuilder objectBuilder = new NativeObjectBuilder();
IManagedBase<int> ib = objectBuilder.GetBaseObject<int>();
ib.DoSomething(); This trick works well for primitive types. But for other complex types, you may need to write wrappers and use it.
Hope that helps
PS: I wrote this code directly on CP editor and you may get some minor syntax error.
modified on Saturday, October 10, 2009 1:03 AM
|
|
|
|
|
Hi all,
I want convert System::String* str[] to const char* chars[] array for one of mu application!
System::String* str[] is a parameter to function. And this function is called from c#
any have idea how this conversion happens?
|
|
|
|
|
SaveTigers wrote: System::String* str[]
Does that even compile? I don't think you can write System::String* str[] . Do you want to convert managed string to const char* ?
|
|
|
|
|
Hey thanks for reply Navaneeth,
Got it!
I am doing something like this
char *abc[100];
for(int i = 0; i < ss->Count; i++)
{
abc[i] = (char*)(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(ss[i])).ToPointer();
}
the above code is working file where ss is System::String* ss[] as function argument
I spend 2 days to get it working!!!
Now the problem is with System::Double dd[][] I want to convert it to double[][] used in Unmanaged C++
how should I use System::Double dd[][] in managed C++
I am getting this sort of error
error C2440: 'initializing' : cannot convert from 'double __gc *' to
'double'
I tried many permutation but could n0t get through!!
Navaneeth any idea how to do this conversion!
Thanks in advance!
|
|
|
|
|
Ahh you are using old syntax. In the new C++/CLI syntax, System::String* is invalid. Old syntax is obsolete and don't use it if you have a compiler that supports new syntax. Here is how you use 2 * 2 double array in C++/CLI.
array<double, 2>^ doubleArray = gcnew array<double, 2>(2, 2);
doubleArray[0 , 0] = 10;
doubleArray[0 , 1] = 11;
doubleArray[1 , 0] = 12;
doubleArray[1 , 1] = 13;
|
|
|
|
|
Hey thanks Navneeth!
Actually what I am trying to do is...
I have on Static DLL which I am exposing to c# using Managed C++ library, so that I can use it directly, will not have overhead of registering and de-registering (id I develop COM DLL to expose static DLL functionality to C# client)
Now, the problem is I am Passing "System::Double dd[][]" as argument to Managed C++ as a function argument and I want to convert the passed double array to array used in the function(so that I can forward it to Static DLL), However while doing
doubleArray[0 , 0] = dd[0][0];
I am clueless about how to get rid of this error
Can I use this code provided by you
array<double, 2>^ doubleArray = gcnew array<double, 2>(2, 2);
doubleArray[0 , 0] = 10;
doubleArray[0 , 1] = 11;
doubleArray[1 , 0] = 12;
doubleArray[1 , 1] = 13;
or there is any other way to type cast?
Thanks in advance Navneeth!!
|
|
|
|
|
You want to accept managed array as parameter and pass that to a native function that expects a native double array, right? Here is how you do it:
void Function(array<double, 2>^ doubleArray)
{
double nativeArray[2][2];
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 2; j++)
{
nativeArray[i][j] = doubleArray[i , j];
}
}
} I reiterate, please avoid using the obsolete syntax and use C++/CLI style syntax. Compile with /clr switch rather than /clr:oldsyntax .
|
|
|
|
|
|
I can't use ofstream in my form..
it says...
Unknown Identifier.
And YES I included "fstream"...
But it's not fstream.h... it's the simple fstream.
What should I do?
|
|
|
|
|
How do you use savefiledialog?
|
|
|
|
|
Fenix2 wrote: How do you use savefiledialog?
Like this[^]!
|
|
|
|
|
Now... how do I write a variable in it?
It only uses stream.write and that write only writes arrays..
Plus I'm having hard time using arrays..
It seemed like streamwriter.writeline would work fine.
But it's different from stream...
what can I do?
|
|
|
|
|
Fenix2 wrote: Now... how do I write a variable in it?
In what?
Fenix2 wrote: what can I do?
From the above questions, I think spend some time studying C++/CLI. There is too much here for a simple answer.
|
|
|
|
|
I can't study it more than that..
I don't have a book,
I don't have a class on it,
And furthermore, all the darn examples on C++ web browsers won't work.
I'm trying to write a variable in a file.
I got the dialog working and the creation of the file FINE.
But when it comes to writing arrays wich are definitely the only variable type that has NO Meaning IN LIFE at all...
I used to program in pascal turbo...
But in a whole game programming I never used arrays.
And I'M not gonna start here... You hear me man?
So tell me...
How do I write a variable in a damn file??!?
|
|
|
|
|
Sorry fort this upsetting.
It makes me mad when a guy tells me to study a language when that is Exactly what I am trying to do...
|
|
|
|
|
Fenix2 wrote: It makes me mad when a guy tells me to study a language when that is Exactly what I am trying to do...
Well it does not appear that you are. What you are doing is posting questions one at a time and asking someone here to write the code for you. Studying means actually sitting down with a book, online tutorial etc and working through it until you understand it. The fact that you don't understand arrays suggests you have a long way to go.
|
|
|
|
|
Fenix2 wrote: I don't have a book,
Living in Canada and can't get a book?
Fenix2 wrote: And furthermore, all the darn examples on C++ web browsers won't work.
You may be referring to incorrect links.
Fenix2 wrote: But in a whole game programming I never used arrays.
And I'M not gonna start here
Interesting. So are you looking for a syntax of writing managed arrays? Here is how you write a simple integer array.
array<int>^ arr = gcnew array<int>(2);
arr[0] = 26;
arr[1] = 18; Fenix2 wrote: How do I write a variable in a damn file??!
Here is how you write array of strings to a file.
using namespace System;
using namespace System::IO;
typedef array<String^> StringArray;
void WriteArrayToFile(StringArray^ arr)
{
StreamWriter writer("c:\\test.txt", false);
for each(String^ str in arr)
{
writer.WriteLine(str);
}
} Use it like:
StringArray^ arr = gcnew StringArray(2);
arr[0] = "You need";
arr[1] = "a good book";
WriteArrayToFile(arr); All I can say is, grow up, read the posting guidelines and post your question nicely with relevant code and change your attitude if you expect help from this forums.
If you ever plan to read a book, try this[^]
|
|
|
|
|
Niice
this will probably help me...
I gotta try it...
I'm 22 years old, I don't have money to spend on books... there are poor people on canada and managin to get a 2300$ computer 3 years ago made me full of school loans. (Lol...)
|
|
|
|
|
Fenix2 wrote: I don't have money to spend on books...
Do you have a library near you where you could borrow one?
Even if not, you obviously have access to the internet and there are thousands of good tutorials around, just try searching this site and use google. That's what the rest of us have to do.
|
|
|
|
|
HI all,
I am getting this error since morning, I am clue less as I am working first time on it (I am c# developer).
the code file are as follows and i compied using Commnad prompt
command cl /clr:oldSyntax DemoCPP.cpp
DemoCPP.cpp class
#include "DemoHeader.h"
DemoCPP::DemoCPP()
: Length(0.00), Height(0.00)
{
}
DemoCPP::DemoCPP(double L, double H)
: Length(L), Height(H)
{
}
DemoCPP::~DemoCPP()
{
}
double DemoCPP::getLength()
{
return Length;
}
void DemoCPP::setLength(double L)
{
Length = L;
}
double DemoCPP::getHeight()
{
return Height;
}
void DemoCPP::setHeight(double H)
{
Height = H;
}
void DemoCPP::setDimensions(double L, double H)
{
setLength(L);
setHeight(H);
}
double DemoCPP::Perimeter()
{
return 2 * (Length + Height);
}
double DemoCPP::Area()
{
return Length * Height;
}
header file DemoHeader.h
#pragma once
#using <mscorlib.dll>
__gc class DemoCPP
{
public:
DemoCPP();
DemoCPP(double L, double H);
~DemoCPP();
double getLength();
void setLength(double L);
double getHeight();
void setHeight(double H);
void setDimensions(double L, double H);
double Perimeter();
double Area();
private:
double Length;
double Height;
};
any body have any idea how to resolve this problem?
thanks in advance!
|
|
|
|
|
|
Since this is a DLL, you need to compile with /DLL compiler switch. BTW, why are you using old syntax?
|
|
|
|
|
Thanks for quick response!
Yes I have googled a lot and then placed question here...
the Old command i am using because it is recommended by the VS2005 when i tried to build the project from vs2005
I tried the project type as empty project as well as class library!
still I am getting the same error!
I have created the project using wizard itself!
any further help!
thanks in advance!
|
|
|
|
|
If you have VS, don't do command compilation. I never came across a situation where VS recommended old syntax. If you need to create a fully managed assembly, choose Class Library project type. Use new syntax and compile using /clr:safe .
if you need to communicate with native libraries, compile with /clr switch which will produce mixed assemblies. Since you have VS IDE, best option is to use it to compile rather than doing through command. VS does things like manifest embedding automatically.
|
|
|
|