|
Hello All,
What is the MC++ version of the "Optimizing Event Implementation"
described in the MSDN?
The C# version was implemented as:
-----------------------------------------------------------------
private static readonly object ClickEvent = new object();
public event EventHandler Click
{
add
{
Events.AddHandler(ClickEvent, value);
}
remove
{
Events.RemoveHandler(ClickEvent, value);
}
}
protected virtual void OnClick(EventArgs e)
{
EventHandler clickEventDelegate = (EventHandler)Events[ClickEvent];
if (clickEventDelegate != null) {
clickEventDelegate(this, e);
}
}
-----------------------------------------------------------------------
Frankly, is there no MC++ programmer on the MSDN documentation team?
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hello Paul,
This stuff sure is in dark, poorly-charted waters! It wasn't easy to find, but this seems to be the MC++ translation:
private:
static Object *ClickEvent = new Object();
public:
__event void add_Click(EventHandler *pEH)
{
get_Events()->AddHandler(ClickEvent, pEH);
}
__event void remove_Click(EventHandler *pEH)
{
get_Events()->RemoveHandler(ClickEvent, pEH);
}
protected:
virtual void onclick(EventArgs *e)
{
EventHandler *clickEventDelegate = (EventHandler*)( get_Events()->get_Item(ClickEvent) );
if (clickEventDelegate != null) {
clickEventDelegate(this, e);
}
}
However, I am unsure about how to properly declare ClickEvent , since I cannot find an equivalent to C#'s readonly . Most of this stuff I found in MSDN under the "Managed Extensions for C++ Specification", section "10 Events" ("ms-help://MS.VSCC/MS.MSDNVS/vcmxspec/html/vcManagedExtensionsSpec_10.htm"), and pages on __event and __delegate . MC++ is not exactly well documented!
You are one of the few people on this site who seem interested in delving deeper into MC++. Part of it is probably due to so little attention in documenting MC++ like C# is, as you mentioned. I sure hope this gets more coverage after VS.NET 2003 is released (HINT, HINT, any VS.NET team people out there)...
Cheers
|
|
|
|
|
Hello Jeff,
I know you will be here
Thanks for the support. I am working on MC++ product and do not think C# could cut it.
I have posted the same to the VC.NET news group where there are so many [MSFT] figures but no one is picking the call
Jeff J wrote:
However, I am unsure about how to properly declare ClickEvent, since I cannot find an equivalent to C#'s readonly
This is my problem too. The translation as you coded seems to favor having the event as "User-defined Event Accessor methods", where the user codes the actual event accessors instead of the compiler generation (i.e. the user writes the add_, remove_, and raise_ methods).
I do not know if the raise_ method is required here and could not find any MC++ sample to confirm my thoughts.
I think I have to simply test the above and go with it.
Again, thanks for the support.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
I'm updating some old VC++ code to .NET C++ to talk to a serial device. I cannot get the VC++ code to compile correctly under a managed C++ app. i'm new to the mc++. is this the unmanaged c++ i read about or something else im doing wrong. any help would be great.
megadith@hotmail.com
|
|
|
|
|
Hi all.
Please help to me to disassemble a problem of a call Win32 of functions from unmanaged С++.
You see they are visible in the field of global names.
How to call the ::MessageBox ?
Whether it is possible basically ?
#using <mscorlib.dll>
using namespace System;
using namespace System::Runtime::InteropServices;
#include "iostream.h"
#include "stdio.h"
typedef void * HWND;
#pragma unmanaged
__nogc class UnmanagedClass {
public:
static void metod (void)
{
// ::MessageBox(0," Message_from_Win32 ", " Unmaneged_C++ ", 0);
}
};
[DllImport ("user32")]
extern "C" int MessageBoxA(HWND hWnd, String *pText, String * pCaption,unsigned int uType);
#pragma managed
void main(void)
{
printf (" Message_from_standart_C \n\r");
cout << " Message_from_standart_C++ " << endl;
Console::WriteLine (" Message_from_NET ");
MessageBoxA (0," Message_from_Win32 ", " PInvoke ", 0);
UnmanagedClass::metod();
}
|
|
|
|
|
You do not need to wrap MessageBox (or any other API call) with DllImport marshaling in MC++, unless you need to make it visible to other .Net languages (or other MC++ code). Unmanaged C++ can call API stuff as usual.
However, here is a version of MessageBox I have tried successfully with both MC++ and C#:
[DllImport("user32.dll", CharSet=Auto)]
int<br />
MessageBox(IntPtr hWnd, String *pText, String *pCaption, unsigned uType);
I believe you can use HWND as you defined it within MC++, though I am not sure how other .Net classes would feel about it. An IntPtr is a managed version of void* anyway, so that's what I used. The extern "C" bit is not necessary, and might not even be allowed. I have always used DllImports within a namespace, not globally, but I have used them both within and outside of class definitions.
Cheers
|
|
|
|
|
I am trying to access a simple C++ class and method from c#. My code goes something like this:
mMath.cpp:
#using <mscorlib.dll>
using namespace System::Runtime::InteropServices;
mMath::mMath(){
m_pOperator = new Operator();
}
int mMath::mAdd(int iIn1, int iIn2){
int mAns = m_pOperator->Add(iIn1, iIn2);
return mAns;
}
mMath.h:
#include "Operator.h"
using namespace System;
public __gc class mMath: public IDisposable{
Operator __nogc* m_pOperator;
public:
mMath();
~mMath();
//and an mMath dispose method
int mAdd(int i1, int i2);
};
Operator.cpp:
#include "stdafx.h"
#include <string.h>
#include "mMath.h"
#include "Operator.h"
Operator::Operator(void){}
int Operator::Add(int in1, int in2){
int ans = (in1 + in2);
return ans;
}
and Operator.h:
#pragma once
__nogc
class Operator{
public:
Operator();
int Add(int in1, int in2);
};
Created the C++ code in Visual Studio as an Extended Stored Procedure project. Compiled the C++ code into a .dll and referenced it in my C# Smart Device Application Project. When I try to run it in the emulator it won't create an instance of the mMath object:
c# code:
mMath mm = new mMath();
I get a System.TypeLoadException with message TypeLoadException.
All help will be greatly appreciated... I've tried to follow sample tutorials but I've run out of resources! Thanks!
pj
|
|
|
|
|
I am not sure about what is causing your TypeLoadException, but did you try testing your classes within the same MC++ project? That is, seeing if the classes run in a plain MC++ console project without putting them into a DLL. That might provide some clues.
Incidentally, .Net destructors should be declared protected, and not public as is common in straight C++. The idea is to hide the destructor and promote calling the Dispose method, which can call the destructor if necessary. The CLR interprets a destructor as as the "Finalize" method formally used in .Net, although I doubt it's causing your problem.
Cheers
|
|
|
|
|
What means for visual designing of the forms in maneged C ++ are ?
Or it can be made only by means of a code ?
|
|
|
|
|
Right now, there is no GUI (visual) designer for managed C++. However, VS.Net 2003 will have one, and last I heard, is due to be released in February.
Cheers
|
|
|
|
|
I read in one article that there is a integrited Crystal Report in VC.NET
is that true, if yes could anybody tell me how to use that(a simple example).
thanx.
|
|
|
|
|
Hello All,
I am getting frustrated now....
How do I store cursors and retrive them from a .NET assembly dll?
The resource file support does not seems to extend to cursors. I am
building components not an application and wish to add several cursors
to the component or resource only dll.
Any help?
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
im having do an arm animation ..
with the arm consisting of say 3 basic rectangle bitmaps representing the upper arm
fore arm and the
palm..connected to each other as the usual human arm
they all move in the same plane therefore 2d is ok.
movement is to include translation as well as rotation of every arm...
this includes basically translation and rotataion of the 3 primary bitmaps as well....
as rotation of a bitmap by a specific angle is a tiresome process unless i am to use asm ....
and in this case the rotation will be a major part as for smooth rotation from 0-60 degrees say..requires me to iterate the rotation by an increment until it is 60 degrees.....
ive heard of sprites...do u suggest that i should store all the rotation sprites of all 3 arms and then blt the respective sprite based on the degree of rotation....????
i havent come across any sprite examples that dont use directx....is there any??
do advice if any other solution is possible..
Regs
fordge
note:the arm cannot be drwan geometrically and has to be a bitmap
|
|
|
|
|
I am trying to build the following program as win32 console project with VS.NET which mysteriously produce no output from << operator.
It works if I use printf instead.
Can someone please point me where the problem is?
Thanks
#include <iostream.h>
class X
{
public:
void f( )
{ cout << 4; }
};
void main()
{
X p;
p.f();
}
|
|
|
|
|
Sorry, HTML is not showing include statement right. Here is the correct code.
#include <iostream.h>
class X
{
public:
void f( )
{ cout << 4; }
};
void main()
{
X p;
p.f();
}
|
|
|
|
|
You have the wrong forum; the Visual C++ forum is for regular C++ questions. However, you might want to use the new-style C++ headers, which omit the ".h":
#include <iostream>
and make sure you include:
using namespace std;
or use "std::cout".
|
|
|
|
|
Thanks Jeff it solved the problem .
Sorry about wrong forum.
|
|
|
|
|
Please, can anyone say me reasons for buying VS.Net and using managed C++ instead unmanaged C++ (and C# instead Java for Web) ?
Except compatibility ( "you can use this applications anywere... where Windows and .Net framework installed, heh ")and fashion reasons %)
I'm sorry for this vulgar question, but i cant find this reasons by myself.
Can anyone help me ?
P.S. I forgot - call "delete" for any called "new" is not a problem for me
WBR NB
|
|
|
|
|
Hello All,
What is the recommended way to handle strings out parameters
of functions/methods?
Interestingly, I could not find single example in any book and just
not confidence on which way will work and across languages like
VB.NET and C#.
Any help?
The simply one I am currently considering (which works) is:
#using <mscorlib.dll>
using namespace System;
using namespace System::Text;
void GetString(StringBuilder* pOut)
{
pOut->set_Length(0);
pOut->Append("Out--string");
}
int _tmain()
{
StringBuilder* pOut = new StringBuilder("In--string");
GetString(pOut);
Console::WriteLine(pOut->ToString());
return 0;
}
Any better solution? Something that could be used in other languages too.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
If all you are looking to do is get a String/StringBuilder back when passed as a parameter, then passing by reference will achieve what you want. Your current example would need to be modified to something like:
void GetString(StringBuilder **pOut)<br />
{<br />
(*pOut)->set_Length(0);<br />
(*pOut)->Append(S"Out--string");<br />
}
This is very COM-like, and both C# and VB.Net prototypes will ask for a reference, such as:
void GetString(ref StringBuilder pOut); //in C#
which would be called like:
GetString(ref pOut);
GetString(ByRef pOut);
GetString(&pOut);
For various reasons, just asking for a pointer to a parameter is not enough with the CLR (unlike in C++); one must ask for a pointer to a pointer in order for the modification to get back to the caller. Your current version may well work when the StringBuilder is not reallocated, but all bets are off after reallocation, since the callee will then have a pointer to a new object (and this is always the case when passing String).
I believe there is also a way to make the call look like:
void GetString(out StringBuilder pOut); //C#
but I have not bothered so far, as I am waiting for finalisation of VS 2003 with possibly further MC++ refinements, and I have also not really needed to do so.
When passing by the CLR's definition of "by ref", you will no longer need to pre-size the StringBuilder before calling GetString():
int _tmain()<br />
{<br />
StringBuilder *pOut = new StringBuilder();<br />
GetString(&pOut);<br />
Console::WriteLine(pOut->ToString());<br />
return 0;<br />
}
That is probably obvious to you, but it is mainly why I have used passing by ref. For example, I have written some MC++ functions that are expected to be called repeatedly. They take StringBuilders by ref specifically so that internal arrays rarely need to be reallocated, and I suspect you might be trying to do the same. I have also done this with plain CLR strings, though reallocation would need to occur on each call:
void GetString(String **ppStr)<br />
{<br />
*ppStr = new String(S"Out--string");<br />
}
However, if the function has no length of string to return, then chars do not have to be allocated for nothing. I hope some of this is valid for your purposes
Cheers
|
|
|
|
|
Hello Jeff,
Thanks so much for taken the time to explain this so well. I tried the pointer to pointer stuff in an out System::Drawing::Rectangle case, and the compile will not work claiming it is a value and that I should use the "__nogc new" instead:
void GetRectangle(Rectangle** pOut)
{
*pOut = new Rectangle(...);
}
Not knowing whether the C++ heap will be accessible or not from other languages, I changed it to reference like this:
void GetRectangle(Rectangle& pOut)
{
pOut.X = ;...
}
However, the IL output from the MC++ seems to carry some VC specific information attached to the parameter:
modopt([Microsoft.VisualC]Microsoft.VisualC.IsCXXReferenceModifier)
So, I got confused as to what will really be accepted as the standard way of doing it.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Well, I just got this response on the VC news group:
There is no real need to change to pointers. C# handles this fine. The
"modopt" means that it is an OPTional MODifier for the signature. When the
C++ compiler sees it it know to treat it as a C++ reference, the C# compiler
will just treat it as a byref parameter.
Ronald Laeremans
Visual C++ team
It seems the modopt stuff is "safe" to work with
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hi Paul,
Thanks for the bit from the Ronald Laeremans; there's nothing like inside info I had been wondering why the compiler treats pointers to __value parameters the same as declaring them as C++ references. Knowing that this stuff is ".Net official" makes me feel better about the future for code I've written. Please feel free to post anything else you get from the inside!
Sorry I didn't cover passing __value types in my first post; I was only talking about types that are already "CLR reference object"/pointer types, when I talked about pointers to pointers. I pass __value types the same way you did (as a C++ reference), and skip the pointer syntax.
Cheers,
Jeff
|
|
|
|
|
I met a problem when I tried to wrap unmanaged class into managed class with managed C++.
First, I built a static library, VcClass.lib, from the following source code with VC++ 6.0 :
/* interface.h */
#include <windows.h>
class CMyClassA
{
public:
BYTE *m_pBuf;
int m_bufLen;
CMyClassA() { m_pBuf = NULL; m_bufLen = 0; }
~CMyClassA() { FreeBuf(); }
HRESULT LoadBuf(BYTE *pBuf, DWORD dwBufLen);
private:
HRESULT FreeBuf(void);
};
class CMyClassB
{
public:
CMyClassB() { m_pA = NULL; }
~CMyClassB() { m_pA = NULL; }
HRESULT Func(CMyClassA *pClassA);
HRESULT Func2(void);
private:
CMyClassA *m_pA;
};
#endif
/* VcClass.cpp */
#include <stdio.h>
#include "interface.h"
HRESULT CMyClassA::LoadBuf(BYTE *pBuf, DWORD dwBufLen)
{
m_bufLen = dwBufLen;
m_pBuf = new BYTE[m_bufLen];
memcpy(m_pBuf, pBuf, m_bufLen);
return 0;
}
HRESULT CMyClassA::FreeBuf(void)
{
m_bufLen = 0;
delete [] m_pBuf;
return 0;
}
HRESULT CMyClassB::Func(CMyClassA *pClassA)
{
m_pA->m_pBuf = pClassA->m_pBuf;
m_pA->m_bufLen = pClassA->m_bufLen;
for (int i=0; i<m_pa->m_bufLen; i++)
printf("buf[%d] = %d\n", i, m_pA->m_pBuf[i]);
return 0;
}
HRESULT CMyClassB::Func2(void)
{
if (m_pA->m_pBuf == NULL) {
printf("buf is empty, call Func() first!\n");
return 1;
}
for (int i=0; i<m_pa->m_bufLen; i++)
printf("buf[%d] = %d\n", i, m_pA->m_pBuf[i]);
return 0;
}
then, I wrote two wrapped classes with VC++ 7.0 and compiled them into a DLL:
#include "interface.h"
using namespace System;
namespace McClass
{
public __gc class McMyClassA
{
public:
McMyClassA() { m_pClassA = new CMyClassA; }
~McMyClassA() { delete m_pClassA; }
int LoadBuf(System::Byte Buf[], int Len)
{
System::Byte __pin * p = &Buf[0];
return m_pClassA->LoadBuf(p, Len);
}
void *GetA() { return (void*)m_pClassA; }
private:
CMyClassA * m_pClassA;
};
public __gc class McMyClassB
{
public:
McMyClassB() { m_pClassB = new CMyClassB; }
~McMyClassB() { delete m_pClassB; }
int Func(McMyClassA *pMA)
{
CMyClassA *pA = (CMyClassA*)pMA->GetA();
return m_pClassB->Func(pA);
}
int Func2(void)
{
return m_pClassB->Func2();
}
private:
CMyClassB * m_pClassB;
};
}
Finally, I wrote an application with C# to call the DLL:
using System;
using McClass;
namespace CSharpApp
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
int i;
McMyClassA classA = new McMyClassA();
McMyClassB classB = new McMyClassB();
Byte[] buf = new Byte[10];
for (i = 0; i<10; i++)
buf[i] = 54;
classA.LoadBuf(buf, 10);
classB.Func(classA);
Console.WriteLine("OK.");
classB.Func2();
Console.WriteLine("OK.");
}
}
}
When I run the C# application, a NullRefrenceException occurred and the additional information is :
Unhandled Exception: System.NullReferenceException: Object reference not set to
an instance of an object.
at CMyClassB.Func(CMyClassB* , CMyClassA* )
at McClass.McMyClassB.Func(McMyClassA pMA)
at CSharpApp.Class1.Main(String[] args)
I think that the exception occurs because I used a wrong approach to pass a pointer of MyClassA into an instance of MyClassB.
So, what is the right way to do it? Data Marshal?
I hope MyClassA is independent on MyClassB, therefore I don’t want to merge MyClassA and MyClassB into one class.
Please help me!
Thank you very much!
|
|
|
|
|
sorry, I made a mistake.
please don't reply.
thanks.
|
|
|
|
|