|
void* p = (void*)(A::f);
C++ compilers are very strict, they want to make absolutly sure you know what you are doing (this is a good thing). If you need to do this you are probubly doing some thing wrong. I recommend that you read up on vetual base classes.
Trust in the code Luke. Yea right!
|
|
|
|
|
I get a runtime error when I cast an object to an interface the class implments. The class and interface are both managed C++, and the cast in done in C#.
I have narrowed the problem down to a simple case:
1) C# constructs an object defined in managed C++
2) C# casts object to a managed C++ interface it implements
3) C# call method on the object after the cast.
If I do this, I get a runtime exception. I have seen an invalid cast exception, and sometimes I get a format exception that says "the format specific is not allowed...". It seems like the runtime gets very confused.
But instead if I do the following;
1) C# constructs a object defined in managed C++
2) C# stores object in variable as its actual type; not the interface
3) C# calls method on class
it all works.
The problem comes when C# casts a managed C++ object to be its interface type (the interface is also defined as a managed C++ interface).
I have not found anyone who has done what I am trying to do, and I have not found any documentaion that talks about this, so perhaps its not recommended.
Does anyone have experience mixing managed C++ and C# with interfaces defined in C++ and casts to the interface being done form C#?
thanks
Bryan
|
|
|
|
|
I got the same experience so i declared the interface in C# Dll.
|
|
|
|
|
So if I declare an interface in C#, can I implement the interface in managed C++ successfully?
|
|
|
|
|
Yes, you can find a sample at http://www.codeproject.com/useritems/SessionState.asp.
look at the source -> tmpSessionSync project.
|
|
|
|
|
I am trying your suggestion. But I have one problem. I have defined an C# interface with a method that returns an object.
How do I define the implementation for this method in C++?
public interface ICOSP_9054_Connection
{
object getConnection( );
}
Originally, when I declared the interface in C++, the method returned a void*. Is there a way to return a void* from a C# method? I can do fine with either approach. The problem is that for some implementors of this method, they will be asking unmanaged C++ code to return an object that I have not defined an interface for so it is easier for me to return a void* (or object).
thanks
Bryan
|
|
|
|
|
public interface ICOSP_9054_Connection
{
object getConnection( );
}
public MyClass : public ICOSP_9054_Connection
{
public:
Object __gc* getConnection()
{
}
};
|
|
|
|
|
I have an app which uses SDI and is written in MFC for its presistence it uses a STL vector. I need to migrate to managed C++ by changing my container to a managed container. I have tried System.Array that didn't work, and either did wrapping the vector. can you please provide a good idea I'm out of ideas.
Sul,R.
Upcoming developer only 2.5 months to go
|
|
|
|
|
System::Array will not provide the STL vector style container. Consider System::Collection::ArrayList. You can derive from the ArrayList and add new methods which match the STL::vector to make the porting easier.
If you still have problems, then post some codes.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hello All,
I have a standard C++ class with MC++ member defined as
gcroot < System::Drawing::Brush __gc* > m_pDotNetBrush;
Somewhere in the codes, I wish to use the brush and trying to
cast it to the appropriate type:
System::Drawing::SolidBrush __gc* pBrush =
__try_cast < System::Drawing::SolidBrush __gc* >(m_pDotNetBrush);
This, however, generates error in the form:
<br />
error C2682: cannot use __try_cast to convert from 'gcroot < T >' to 'System::Drawing::SolidBrush __gc *'<br />
I tried the other standard C++ casts and all failed with same error.
What is supposed to be done in this case?
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Got this response from one Jochen Kalmbach, and it works
Normaly you should do:
System::Drawing::Brush *b;
b = m_pDotNetBrush;
Then you can try to cast it...
System::Drawing::SolidBrush *pBrush =
__try_cast < System::Drawing::SolidBrush* > (b);
--
Greetings
Jochen
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
I'm not at all new to .NET but I am new to MC++ and had some questions for a control I'm working on, which is hosting either the WebBrowser control or MSHTML.
If I declare a managed class with __gc class , can I still derive from ATL templated classes? I know I can use unmanaged function calls within managed methods, but I'm not sure I can mix the two in class definitions. Any help or suggestions would be much appreciated.
Reminiscent of my younger years...
10 LOAD "SCISSORS"
20 RUN
|
|
|
|
|
Hello Heath,
Welcome to MC++. I think you should start by reading the MC++ reference document. It is small and straight. Download the word format and print it if you wish to work with the MC++.
Now, to your question. You cannot derive __gc class from __nogc class or vice versa. You can have each as members (wrapper stuff). For controls you can subclass and superclass where necessary.
In my recent project, we had MFC ActiveX GIS control and wanted to port it to .NET. I quickly reworked the rendering in ATL/WTL and with MC++ got it working.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hi!
I'd like to implement my own Collection that derives from Collection Base. I want the Item-property to have the proper return type instead of Object*. In C# it is easy to implement a Covariant return type:
<br />
class MyData<br />
{<br />
public int Value<br />
{<br />
get { return 5; }<br />
}<br />
};<br />
<br />
class MyCollection : CollectionBase<br />
{<br />
public MyData this[int index]
{<br />
get{ return (MyData)List[index]; }<br />
set{ List[index] = value; }<br />
}<br />
};<br />
In VC++.net, however it does not seem to be possible, as covariant return types are not allowed - at least in VC++.net:
<br />
__gc class MyData<br />
{<br />
__property int get_Value()<br />
{<br />
return 5;<br />
}<br />
};<br />
<br />
[Reflection::DefaultMember(S"Item")]
__gc class MyCollection<br />
: public System::Collections::CollectionBase<br />
{<br />
__property MyData * get_Item(int in_index)
{<br />
return static_cast<MyData*>(List->Item[in_index]);<br />
}<br />
};<br />
Is there any attribute or another way to achieve what I'd like to do?
I am using VS.net 2002. Might this feature be available in vs.net 2003?
Thanks in advance!
- Andre
|
|
|
|
|
Hello Andre,
I am not currently on my .NET machine to investigate your case. However, all my collections for a product, we are about to release, does just that without any problem. I use VS.NET 2003 (but I do not think it is the issue).
To prove the point, here is a code I have copied for a real .NET component.
public:
__property MapTheme* get_Item(int index)
{
return __try_cast<MapTheme*>(List->Item[index]);
}
__property void set_Item(int index, MapTheme* value)
{
List->Item[index] = value;
}
So the problem may not be the issue of "Covariant return types". Do you have implementation for the set_Item property too? Also, your code seems to make the get_Item property private, is that what the actual code you compiled is?
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hi Paul
Just to give you an example:
<br />
public __gc class MyData { };<br />
<br />
public __gc class MyCollection<br />
: public CollectionBase<br />
{<br />
public:<br />
__property MyData * get_Item(int in_index)<br />
{<br />
return static_cast<MyData*>(List->Item[in_index]);<br />
}<br />
<br />
__property void set_Item(int in_index, MyData * in_data)<br />
{<br />
List->Item[in_index] = in_data;<br />
}<br />
};<br />
The (German) output is:
<br />
Covariant4.cpp(19) : error C3815: Der Rückgabetyp der Methode 'MyCollection::get_Item' muss mit dem Typ des letzten Parameters von 'System::Collections::IList::set_Item' übereinstimmen<br />
Covariant4.cpp(18) : Siehe Deklaration von 'MyCollection::get_Item'<br />
Covariant4.cpp(6) : Siehe Deklaration von 'System::Collections::IList::set_Item'<br />
Covariant4.cpp(19) : error C2392: 'MyData __gc *MyCollection::get_Item(int)' : Covariant-Rückgabetypen werden in verwalteten Typen nicht unterstützt<br />
Translated:
C3815: Return value of 'MyCollection::get_Item' must match the type of the last parameter of 'System::Collections::IList::set_Item'
C2392: 'MyData __gc *MyCollection::get_Item(int)': Covariant return types are not supported in managed types
It seems to me as if this has been fixed in vs2003. Damn, I'm looking forward to it
- Andre
|
|
|
|
|
I see, I will try it on my VS.NET 2002 tomorrow and report on the result - glad I made the switch before my company could decide
In any case, VS.NET 2003 is a product designed for the MC++ developer. There is hardly any new for the C#/VB.NET components.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Paul Selormey wrote:
In any case, VS.NET 2003 is a product designed for the MC++ developer. There is hardly any new for the C#/VB.NET components.
Yes, I realized that. In fact, I guess vc++.net 2003 is what vc++.net 2002 should have been if the VC++ team had more time.
- Andre
|
|
|
|
|
VizOne wrote:
Yes, I realized that. In fact, I guess vc++.net 2003 is what vc++.net 2002 should have been if the VC++ team had more time.
I do not think it is an issue of time since it took four years of development from VC++ 6.0 release. With very little improvement in MFC, and some web-stuff updates for ATL four years was enough to do effective work.
May be the resources the VC++ team was cut down in favor of C# and when they saw the developer reaction they went back to push MC++ up a bit.
Anyway, I am back to work and will check on the problem with VS.NET 2002 today.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Paul Selormey wrote:
I do not think it is an issue of time since it took four years of development from VC++ 6.0 release. With very little improvement in MFC, and some web-stuff updates for ATL four years was enough to do effective work.
Or maybe they could only start their work after most parts of .NET framework were done.
It's not the fall that kills you: it's the sudden stop - Down by Law, Jim Jamursch (1986)
|
|
|
|
|
Hello Andre,
I have just tried this with VS.NET 2002 and 2003. I constructed a VS.NET 2002 project using the CollectionBase class and it failed to compile.
Then I opened the project in VS.NET 2003 and it compiled successfully!!!
Please look for an upgrade route now to avoid headache.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Here's some of my code:
...<br />
BtCard = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);<br />
if(WSAGetLastError() == 10047)<br />
{<br />
cout << "Address family not supported by protocol family!" << endl;<br />
goto GetOut;<br />
}<br />
...
The socket function call above gives me the error message listed.
Checked the help documentation. Here's what "they" says on the use of the function:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bluetooth/bluetooth/bluetooth_and_socket.asp[^]
Me, wrong!?! Nah, you just need to change your thinking to make me right.
|
|
|
|
|
Hello Aaron,
Please try the Visual C++ forum for API/VC++/MFC questions. This forum is for MC++.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Is this possible ?
I'm trying to use a TabControl and TabPage.
I can place the TabControl, and a couple of TabPage, and single items in the TabPage
Here, m_pManagerPage and m_pOperationPage are Form, that I wish to Add to the m_pOperationTabPage (instead of m_pButton1).
The Question is, Can a Form like a modeless dialog within a dialog (like in MFC), that can be placed within another Form ?
m_pTabControl = new TabControl;
m_pButton1 = new Button;
m_pButton1->Text = S"Text";
m_pButton1->Size = System::Drawing::Size( 70, 25 );
m_pButton1->Location = Point( 10, 10 );
m_pManagerTabPage = new TabPage( S"Manager" );
m_pOperationTabPage = new TabPage(S"Command" );
m_pTabControl->TabPages->Add( m_pManagerTabPage );
m_pTabControl->TabPages->Add( m_pOperationTabPage );
m_pOperationPage = new OperationPage();
m_pOperationPage->Hide();
m_pManagerPage = new ManagerPage();
m_pManagerPage->Hide();
m_pOperationTabPage->Controls->Add ( m_pButton1 );
m_pTabControl->SelectedIndexChanged += new EventHandler(this, &FloatingWindow::ChangePage );
Controls->Add( m_pTabControl );
Thanks.
Maximilien Lincourt
For success one must aquire one's self
|
|
|
|
|
![Go to Parent](https://www.codeproject.com/App_Themes/CodeProject/Img/arrow-up24.png) For your needs, I think UserControl will do. However, it is possible to place a form in a form. This key is setting the TopLevel property to false before adding and making sure it is visible.
It will even appear in the Designer, just that the TopLevel part will be deleted in the designer.
The following is a complete source which will compile to display a form in a form, try it...
#pragma once
namespace MustGo2
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
public __gc class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
}
protected:
void Dispose(Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super::Dispose(disposing);
}
private: System::Windows::Forms::Form* panel1;
private:
System::ComponentModel::Container * components;
void InitializeComponent(void)
{
this->panel1 = new System::Windows::Forms::Form();
this->panel1->TopLevel = false;
this->SuspendLayout();
this->panel1->AutoScaleBaseSize = System::Drawing::Size(5, 12);
this->panel1->ClientSize = System::Drawing::Size(248, 198);
this->panel1->FormBorderStyle = System::Windows::Forms::FormBorderStyle::Fixed3D;
this->panel1->Location = System::Drawing::Point(16, 16);
this->panel1->Name = S"panel1";
this->panel1->Visible = true;
this->AutoScaleBaseSize = System::Drawing::Size(5, 12);
this->ClientSize = System::Drawing::Size(292, 266);
this->Controls->Add(this->panel1);
this->Name = S"Form1";
this->Text = S"Form1";
this->ResumeLayout(false);
}
};
}
What I did is to place a planel using the Designer and then replaced it with Form class in the code
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|