|
Hi,
I posted this on MS's "Visual C++ Language" forum a few days ago without getting a useful answer. I'm hoping somebody (Nish??) here can help. I'm pretty desperately needing a solution at this point.
We are doing a transition project where we are wrapping unmanaged C++ code with C++/CLI (VS 2005) managed classes. The various methods and properties on a given managed wrapper class are mostly just pass-through calls to the wrapped C++ class.
Mostly this works fine. Sometimes, however, the call from the managed code ends up in the wrong C++ function. IOW:
void ManagedMethod1( void )
{
m_pUnmanagedObject->Func1();
}
actually calls m_pUnmanagedObject->Func20().
So far, it seems that every time this happens, the called method on the UNmanaged C++ class is declared "virtual"; it also seems that the incorrect method that is actually called is also declared virtual. I have tried in one or two situations to change the legacy class method to non-virtual and it fixed the problem. However, that isn't a very general or useful solution.
The unmanaged code is in a DLL, and the managed wrappers are in an assembly DLL. I've cleaned and rebuilt both multiple times, as well as the C# test driver program.
There is another problem that is probably related that I've found with another virtual function, this one taking a parameter (the first problems above were with virtual functions taking no parameters). Tracing in the managed wrapper code in Disassembly mode, there is what looks like a call to something called MarshalCopy, which calls the copy c'tor for the class of the passed parameter. This call appears to execute without error; however, when execution returns from that function, it returns to a completely different place than it was called from, which needless to say, is fatal pretty quickly.
I'm sure I'm doing something wrong and/or stupid; perhaps I need some kind of explicit marshalling (though I thought you didn't need this with C++ interop), or some compiler switch or something. But I've looked and looked, and can't find anything.
I would GREATLY appreciate any help or suggestions.
Thanks.
Doug
|
|
|
|
|
Well, embarrassingly enough, I was doing something pretty stupid - trusting the compiler to rebuild everything necessary automatically.
Apparently I never first "Cleaned" then "REbuilt" both projects at the same time. When I did that, the problem went away.
So, I was stupid for not doing this right away, but... it seems the compiler is somehow defective, since I did "Build" both projects many times.
I guess this is better than an actual compiler bug that MS wouldn't fix for a year!
Doug
|
|
|
|
|
now i have a CString variable contain an integer value
i wanna convert the CString to int so i used atoi() function
<br />
CString strNumber = "00123"<br />
int nNumber = atoi(strNumber);<br />
then nNumber will contain (123)and it ignore the Zeros
so what if i need these Zeros, what should i do
also if i wrote
int x = 0110;
x will result into (72)
could anybody explain that
thnx 4 ur time and concern
|
|
|
|
|
hello,
In a integer you can't keep the zeros, so if you want the zeros at the left you have to use string and so on,
About the second problem, if you put 0 at the left, you are using octal system so,
0110 = 0*8^3+1*8^2+1*8+0 = 72
Regards
-- modified at 10:03 Wednesday 11th October, 2006
|
|
|
|
|
singersinger wrote: so what if i need these Zeros, what should i do
padding zeros is a display formatting operation and has nothing to do with the value of the intrinsice numeric type (int, long, etc.)
singersinger wrote: x will result into (72)
if you want x = 110 write:
int x = 110;
otherwise the leading zero is interpreted by the compiler to mean "octal" just as leading 0x means hexadecimal.
led mike
|
|
|
|
|
note: int x;
x= 0110; //oct value 0"number", base 8
x= 0x110; //hex value 0x"number", base 16
x= 110; //dec value, base 10
so a 0110(base 8) number is 72(base 10)
* use Windows calculator to check the above values
you can NOT keep the zeros if you use a "int" type
|
|
|
|
|
Hello,
To convert from CStrin to String^ I have done it like this:
CString TextAuxStr;
String^ TextCLR;
TextAuxStr = "Test";
TextCLR = gcnew String(TextAuxStr.GetBuffer());
Is there any other way to do it??
Thank you
Regards
|
|
|
|
|
The method you've used is the best way to do it (though there are other ways too).
|
|
|
|
|
Hello,
I'm using treeview with Windows forms, and I would like to select an ITEM of the tree when and event occurs, How can I do this??? I have been trying to use the TreeView.Select() , but I don't manage to make it work.
Thank you
Regards
|
|
|
|
|
From my View class, I select an Item like this:
CPoint PointOnClient( currentMousePointinScreenCoordinates);
ScreenToClient( &PointOnClient);
UINT uFlags;
HTREEITEM hItem = GetTreeCtrl().HitTest( PointOnClient, &uFlags);
GetTreeCtrl().Select( hItem, TVGN_CARET);
It would help to see what you are doing in your code.
"We trained hard, but it seemed that every time we were beginning to form up into teams we would be reorganised. I was to learn later in life that we tend to meet any new situation by reorganising: and a wonderful method it can be for creating the illusion of progress, while producing confusion, inefficiency and demoralisation."
-- Caius Petronius, Roman Consul, 66 A.D.
|
|
|
|
|
I am using a treeView
private: System::Windows::Forms::TreeView^ TreePOver;
I created
this->TreePOver = (gcnew System::Windows::Forms::TreeView());
It is easy to now which node have you selected
String^ NodoStr;
NodoStr = "";
NodoStr = TreePOver->SelectedNode->Text::get();
And after I make a case...
But now I want to select a specific node of the treeView
In my tree for example:
this->TreePOver->Name = L"TreePOver";
treeNode1->Name = L"Node1";
treeNode1->Text = L"Node1";
treeNode2->Name = L"Node2";
treeNode2->Text = L"Node2";
treeNode3->Name = L"Node3";
treeNode3->Text = L"Node3";
If I make:
NodoStr = TreePOver->SelectedNode->Text::get();
I will get Node1, Node2, Node3 in each case, but now I want to select one of the nodes in the tree.
Thank you
|
|
|
|
|
I am working with the .NET SerialPort class and I want to output some text on a textbox when a data received event occurs on the serial port. However i get this exception.
"An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
Additional information: Cross-thread operation not valid: Control 'richTextBox1' accessed from a thread other than the thread it was created on."
So to solve this I found out calling the invoke method is the right way to go. I found some C# code which is a good example, I was wondering if anyone can please convert it to C++/CLI code for me.
private void Log(LogMsgType msgtype, string msg)
{
rtfTerminal.Invoke(new EventHandler(delegate
{
rtfTerminal.SelectedText = string.Empty;
rtfTerminal.SelectionFont = new Font(rtfTerminal.SelectionFont, FontStyle.Bold);
rtfTerminal.SelectionColor = LogMsgTypeColor[(int)msgtype];
rtfTerminal.AppendText(msg);
rtfTerminal.ScrollToCaret();
}));
}
|
|
|
|
|
Namespaces are great - but there are rather many of them in .net, even just in the framework.
So I've been wondering how to deal with them in a safe yet readable way. I don't want to write System::Windows::Forms::DialogResult::OK everytime a use a dialogue box. Neither do I want to simply make every class inside System::Windows::Forms part of the global namespace via a using directive. This question is replicated for the other nested .net namespaces which need to be used.
So the solution I'm considering is this:
<br />
<br />
<br />
namespace Rclsoftware
{<br />
namespace Forms = System::Windows::Forms;<br />
}<br />
<br />
<br />
if(Forms::DialogResult::OK == dlg.ShowDialog(this))<br />
{<br />
}<br />
I'd be interested to hear what people think of this approach, and if there are any potential problems I may have overlooked.
www.rclsoftware.org.uk
|
|
|
|
|
You can do this:
using System::Windows::Forms::DialogResult;
to move just that object into the current scope (note it's using , not using namespace ). That's a C++ rule, though, so I don't know if/how well it works with .Net namespaces/types.
|
|
|
|
|
Mike,
Yes, it does work with C++/CLI.
|
|
|
|
|
Really? I didn't know that.
That would actually make things worse from my point of view, because OK would effectively be in the global namespace.
|
|
|
|
|
zaccheus wrote: That would actually make things worse from my point of view, because OK would effectively be in the global namespace.
Only if you put the using statement in global scope.
|
|
|
|
|
Well yes, that's why I said 'effectively'.
As I explained, I'm talking about the top level namespace that all my code lives in. From all of my code's point of view, OK would be an unqualified identifier which might as well be global.
I'm trying to resolve a very general problem: How to handle all the various namespaces in a readable fashion, without bringing unwanted/unexpected identifiers into scope.
|
|
|
|
|
zaccheus wrote: namespace Forms = System::Windows::Forms;
is a namespace alias. According to Microsoft's documentation:
A namespace alias definition declares an alternate name for a namespace. The identifier is a synonym for the specified namespace and becomes a namespace alias. A namespace name or alias must be different from all other identifiers in its declarative region. A global namespace name or alias must be different from all other global entity names in the program.
I don't see any problems with using namespace alias when you are careful with your choice of an alternate name for one.
George
|
|
|
|
|
Indeed.
The 'declarative region' in this case is my own namespace, so identifier conflicts are easy to avoid.
Of course the alias could be given any name, but the code is easy to read if I use the original namespace name, because the other source files then don't care whether I've done using System::Windows; or namespace Forms = System::Windows::Forms;.
|
|
|
|
|
I am trying to overload the operator () be it keeps telling me that there is not a function that takes 2 arguements. I am using it to pass to unsigned values to reference a point in a 2 dimension array and then assign it to another varible. Can anyone post some examples to see if I have declared correctly as well as using it correctly.
here is something like what I have
unsigned i(0);
unsigned j(0);
a = b(i, j);
I also have an overload for the = operator as well if that makes a difference.
Thanks in advance for any info.
|
|
|
|
|
Your example seems to be missing some bits...
Something like this i think
unsigned int i(int val);
unsigned int i(int val, int val2);
that's a example of operator overloading
You can call those functions like this for example...
i(1);
i(1,2);
Correct me if i'm wrong i'm new to programming too, that's what you wanted to do right?
|
|
|
|
|
Actually unsigned i(0) and unsigned j(0) are variables not overlaods that are intialized to 0. i and j are used to store variables used as index location and then I pass those with the overload like this A(i,j) in hopes to get a reference to the value in that position of the array and assign it to another value like this B = A(i,j).
Some additional information: I have 2 user defined types A,B from above. Type A is an array of B's.
|
|
|
|
|
Hello,
I am trying to translate a component from C# to C++/CLI.
This component is in this link http://www.codeproject.com/csharp/persistwindowstate.asp[^]
I want to translate this code:
private Form mParentForm;<br />
<br />
[Browsable(false)]<br />
public Form Form<br />
{<br />
get<br />
{<br />
if (this.mParentForm == null)<br />
{<br />
if (this.Site.DesignMode)<br />
{<br />
IDesignerHost dh = (IDesignerHost)this.GetService(typeof(IDesignerHost));<br />
if (dh != null)<br />
{<br />
Object obj = dh.RootComponent;<br />
if (obj != null)<br />
{<br />
this.mParentForm = (Form)obj;<br />
}<br />
}<br />
}<br />
}<br />
return this.mParentForm;<br />
}<br />
<br />
set<br />
{<br />
if (this.mParentForm != null)<br />
return;<br />
if (value != null)<br />
{<br />
this.mParentForm = value;<br />
<br />
mParentForm.Closing += new System.ComponentModel.CancelEventHandler(OnClosing);<br />
mParentForm.Resize += new System.EventHandler(OnResize);<br />
mParentForm.Move += new System.EventHandler(OnMove);<br />
mParentForm.Load += new System.EventHandler(OnLoad);<br />
<br />
mWindowInfo.Width = mParentForm.Width;<br />
mWindowInfo.Height = mParentForm.Height;<br />
this.mRegistryPath = "Software\\" + this.mParentForm.CompanyName + "\\" + System.Reflection.Assembly.GetEntryAssembly().GetName().Name;<br />
this.mXMLFilePath = System.IO.Directory.GetParent(System.Reflection.Assembly.GetExecutingAssembly().Location).ToString() + "\\WindowStateInfo.xml";<br />
this.mWindowStateInfo_DR = mWindowState_DS.WindowStateInfo.NewRow();<br />
}<br />
}<br />
}
Can anybody help me?.
Thanks in anticipation.
Tomas.
|
|
|
|
|
You might be interested in trying out the demo of our Instant C++ C# to C++/CLI converter. It produced the following for your sample (you may have one or two tweaks to do - let me know how it works for you):
private:
Form ^mParentForm;
public:
[Browsable(false)]
property Form ^Form
{
Form ^get()
{
if (this->mParentForm == nullptr)
{
if (this->Site->DesignMode)
{
IDesignerHost ^dh = safe_cast<idesignerhost^>(this->GetService(IDesignerHost::typeid));
if (dh != nullptr)
{
System::Object ^obj = dh->RootComponent;
if (obj != nullptr)
{
this->mParentForm = safe_cast<form^>(obj);
}
}
}
}
return this->mParentForm;
}
void set(Form ^value)
{
if (this->mParentForm != nullptr)
return;
if (value != nullptr)
{
this->mParentForm = value;
// subscribe to parent form's events
mParentForm->Closing += gcnew System::ComponentModel::CancelEventHandler(this, &OnClosing);
mParentForm->Resize += gcnew System::EventHandler(this, &OnResize);
mParentForm->Move += gcnew System::EventHandler(this, &OnMove);
mParentForm->Load += gcnew System::EventHandler(this, &OnLoad);
// get initial width and height in case form is never resized
mWindowInfo->Width = mParentForm->Width;
mWindowInfo->Height = mParentForm->Height;
this->mRegistryPath = "Software\\" + this->mParentForm->CompanyName + "\\" + System::Reflection::Assembly::GetEntryAssembly()->GetName()->Name;
this->mXMLFilePath = System::IO::Directory::GetParent(System::Reflection::Assembly::GetExecutingAssembly()->Location)->ToString() + "\\WindowStateInfo.xml";
this->mWindowStateInfo_DR = mWindowState_DS::WindowStateInfo::NewRow();
}
}
}
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C# to C++ converter, VB to C++ converter
Instant Python: VB to Python converter
|
|
|
|