|
Is there a way i can contact you, Lim? I can be reached at jubithn@nway.in
Regards
Jubith Nambradth
|
|
|
|
|
Operator new allocates memory from the heap, on which an object is constructed. Standard C++ also supports placement new operator, which constructs an object on a pre-allocated buffer. This is useful when building a memory pool, a garbage collector or simply when performance and exception safety are paramount (there's no danger of allocation failure since the memory has already been allocated, and constructing an object on a pre-allocated buffer takes less time):
void placement() {
char *buf = new char[1000]; //pre-allocated buffer
string *p = new (buf) string("hi"); //placement new
string *q = new string("hi"); //ordinary heap allocation
cout
|
|
|
|
|
Placement New/Delete
In C++, operators new/delete mostly replace the use of malloc() and free() in C. For example:
class A {
public:
A();
~A();
};
A* p = new A;
...
delete p;
allocates storage for an A object and arranges for its constructor to be called, later followed by invocation of the destructor and freeing of the storage. You can use the standard new/delete functions in the library, or define your own globally and/or on a per-class basis.
There's a variation on new/delete worth mentioning. It's possible to supply additional parameters to a new call, for example:
A* p = new (a, b) A;
where a and b are arbitrary expressions; this is known as "placement new". For example, suppose that you have an object instance of a specialized class named Alloc that you want to pass to the new operator, so that new can control allocation according to the state of this object (that is, a specialized storage allocator):
class Alloc {/* stuff */};
Alloc allocator;
...
class A {/* stuff */};
...
A* p = new (allocator) A;
If you do this, then you need to define your own new function, like this:
void* operator new(size_t s, Alloc& a)
{
// stuff
}
The first parameter is always of type "size_t" (typically unsigned int), and any additional parameters are then listed. In this example, the "a" instance of Alloc might be examined to determine what strategy to use to allocate space. A similar approach can be used for operator new[] used for arrays.
This feature has been around for a while. A relatively new feature that goes along with it is placement delete. If during object initialization as part of a placement new call, for example during constructor invocation on a class object instance, an exception is thrown, then a matching placement delete call is made, with the same arguments and values as to placement new. In the example above, a matching function would be:
void operator delete(void* p, Alloc& a)
{
// stuff
}
With new, the first parameter is always "size_t", and with delete, always "void*". So "matching" in this instance means all other parameters match. "a" would have the value as was passed to new earlier.
Here's a simple example:
int flag = 0;
typedef unsigned int size_t;
void operator delete(void* p, int i)
{
flag = 1;
}
void* operator new(size_t s, int i)
{
return new char[s];
}
class A {
public:
A() {throw -37;}
};
int main()
{
try {
A* p = new (1234) A;
}
catch (int i) {
}
if (flag == 0)
return 1;
else
return 0;
}
Placement delete may not be in your local C++ compiler as yet. In compilers without this feature, memory will leak. Note also that you can't call overloaded operator delete directly via the operator syntax; you'd have to code it as a regular function call.
[from web page : http://www.glenmccl.com/tip_025.htm[^]]
|
|
|
|
|
1. Windows XP SP2.
2. Firewall on. Open Port TCP 135 and optionally Port UDP 135.
-- modified at 3:31 Thursday 16th February, 2006
|
|
|
|
|
There are 2 points I recently discovered about using comments in an INI file :
1. Comments must occupy a sinle line and not be part of a <lhs>=<value> string. For example :
[TEST]
TEST=abc ; abc
The value for "TEST" is actually "abc ; abc"
2. It seems the semi-colon (;) is the official comment-start character. Hence you cannot name a <lhs> as ";TEST" but you can name one as "#TEST".
|
|
|
|
|
If you try to instantiate a VB Active X Control (e.g. MSWINSCK.OCX) and get the CLASS_E_NOTLICENSED (0x80040112L) error, it could really be due to the fact that the license for using the control is not installed in the target machine.
One way to resolve this is to install the VB IDE in the target machine. If this is not an option, create an installation prgram via the VB supplied setup system. The licences for using the VB controls will then be installed on the target system.
|
|
|
|
|
Hi,
I made a com component in C# but I don't know how to call it from a VC++ environment(the steps to register it ,etc..)
Thanks
emmy
|
|
|
|
|
Hello meesho,
Just like a normal COM DLL or EXE, a .NET module which has been wrapped as a COM module needs to have its information written into the registry in order for the COM sub-system to locate it and load it into memory for a client.
REGASM.EXE
----------
This is achieved via the REGASM.EXE utility. REGASM performs similarly to the well-known REGSVR32.EXE utility which is used to register COM modules. REGASM uses the metadata contained inside a .NET assembly to generate COM-equivalent information which are then used to insert entries into the registry.
The entries written into the registry include the CLSIDs and ProgIDs of .NET classes which are exposed as COM classes. This registration process is important for COM clients in the discovery and loading process.
Call the REGASM.EXE utility inside the Visual Studio .NET command prompt as folows :
regasm <.NET DLL Assembly Name> /tlb
The "/tlb" flag commands REGASM.EXE to produce a Type Library File (.TLB) for the .NET Assembly. It is useful for your VC++ client to import.
In your VC++ code, you import the .TLB file using the #import keyword, e.g. :
#import "(TLB file path)";
GACUTIL.EXE
-----------
Next, for ease of discovery and loading by the .NET CLR engine, your .NET DLL Assembly -should- be registered into the GAC (Global Assembly Cache). This is not 100% required but will make life must easiler for your client apps.
In order that a .NET module be registered to the GAC, it needs to be digitally signed. This requires a Strong Name Key (SNK) file. You can create an SNK file using the "sn.exe" .NET utility.
Another step to take is to set the path of the SNK file in the AssemblyKeyFile attribute in the AssemblyInfo.cs file :
[assembly: AssemblyKeyFile("..\\..\\KeyFile.snk")]
To register an assembly into the GAC, we use the GACUTIL.EXE utility. For example :
gacutil -i <.NET DLL Assembly Name>
An alternative to using GACUTIL.EXE is to copy your DLL Assembly into a folder location that can be discovered by the .NET CLR.
Give it all a try, meesho. Let me know if you need further clarifications.
Best Regards,
Bio.
|
|
|
|
|
.NET Components working as COM Objects (wrapped inside COM-Callable Wrappers) are designated being able to survive as STA or MTA objects. That is they support "BOTH" apartment types.
-- modified at 18:47 Friday 25th November, 2005
|
|
|
|
|
mysteron 11/10/2005 11:31 AM PST
I was reading somewhere that 'every STA needs it's own message pump' .. does
this also apply to the scenario where an *inproc* object creates a bunch of
worker threads (and makes those threads STA's by calling CoInitalize(NULL))
.... I have a test app here that is an inproc control that does just this ..
spawns a bunch of worker threads, makes them into STA's and marshals
interfaces into them from the main STA .. and there's only one message pump
pumping.. out in the container app ... and it all seems to work just fine...
TIA
|
|
|
|
|
Brian Muth 11/10/2005 12:50 PM PST
"mysteron" <acornatom66@yahoo.com> wrote in message
news:eP1L0yi5FHA.2020@TK2MSFTNGP10.phx.gbl...
>I was reading somewhere that 'every STA needs it's own message pump' ..
>does this also apply to the scenario where an *inproc* object creates a
>bunch of worker threads (and makes those threads STA's by calling
>CoInitalize(NULL)) ... I have a test app here that is an inproc control
>that does just this .. spawns a bunch of worker threads, makes them into
>STA's and marshals interfaces into them from the main STA .. and there's
>only one message pump pumping..
Not true. Each thread lives in its own STA, and each of those has a message
pump as well.
Brian
|
|
|
|
|
Alexander Nickolov 11/10/2005 6:05 PM PST
I assume you mean your worker threads are blocking on an
event or something waiting for work to come. Try running
Word and notice how long it takes to start. The problem is
it is a DDE server and DDE uses broadcast messages.
Since your threads are not dispathing their message queues,
the DDE broadcast hangs (until it times out) waiting for
responses from any top-level windows on a blocked thread.
Note DDE is not the only piece of code to broadcast
messages - open sysedit, edit win.ini and save and this
results in a WM_WININICHANGE message being broadcast
too. (At least that's my memory from Win9x... A quick
check in MSDN Library reveals this has been superseded
by WM_SETTINGCHANGE today, but the principle is the same.)
The moral is: "seems to work" does not equal "works".
--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@mvps.org
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================
|
|
|
|
|
By: mysteron In: microsoft.public.win32.programmer.ole
i'm having trouble seeing this hidden window in spy++ ... soes anyone know
if there are any issues that might be preventing me from peeking into this
window and watching the COM calls as they are invoked?
|
|
|
|
|
Subject: Re: OleMainThreadWndClass in spy++ 11/10/2005 9:26 AM PST
By: Brian Muth In: microsoft.public.win32.programmer.ole
Just wondering if you might find COMSpy or COMTrace tools useful for your
project?
http://www.blunck.info/comtrace.html
Brian
|
|
|
|
|
by : mysteron
thanks - i was looking for tools like this... even pondering writing my own
"Brian Muth" <bmuth@mvps.org> wrote in message
|
|
|
|
|
By : Igor Tandetnik.
mysteron <billg@microsoft.com> wrote:
> i'm having trouble seeing this hidden window in spy++ ... soes anyone
> know if there are any issues that might be preventing me from peeking
> into this window and watching the COM calls as they are invoked?
It's a so called message-only window (see CreateWindow, HWND_MESSAGE).
These don't show in Spy++.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
|
|
|
|
|
You can only see it on Win9x (including Me) and Win NT4
and before. Starting with Win2K COM uses a lightweight
messaging window (a child of HWND_MESSAGE) which you
can't see with Spy++.
--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@mvps.org
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================
|
|
|
|
|
I'm trying to find some decent documentation about how things work down at
the proxy/stub level in apartment threaded COM ... haven't found much so
far.
Q: anyone know where I can find a really good detailed description of how
all that is implemented?
Q: in a simple scenario, two STA's in a single process, talking to each
other -what exactly is COM doing with message queues and worker threads
inside the proxy/stub? does it boil down to a simple sendmessage from one
thread to the other .. or is it a postmessage? My understanding is that it
is the latter.
Q: this isn't a COM question as such but i'd like your opinion on this ..
two processes A and B are running. They each create a window. At random
intervals they do a sendmessage to the opposite process. Isn't this a clear
invitation to deadlock on windows? Same of course if A and B are threads in
the same process.. right?
TIA
|
|
|
|
|
Reply :
See inline.
--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@mvps.org
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================
"mysteron" <billg@microsoft.com> wrote in message
news:utgI$oZ5FHA.632@TK2MSFTNGP10.phx.gbl...
> i'm trying to find some decent documentation about how things work down at
> the proxy/stub level in apartment threaded COM ... haven't found much so
> far.
>
> Q: anyone know where I can find a really good detailed description of how
> all that is implemented?
If you manage to find one, I'd love to get the link as well...
>
> Q: in a simple scenario, two STA's in a single process, talking to each
> other -what exactly is COM doing with message queues and worker threads
> inside the proxy/stub? does it boil down to a simple sendmessage from one
> thread to the other .. or is it a postmessage? My understanding is that it
> is the latter.
Both can be used depending on the interface. Normally COM uses
PostMessage, unless the method specifies the [input_sync] attribute.
Very few interfaces use that, mostly ones dealing with OLE and
ActiveX Documents. Alas, it's very poorly documented, you'll be hard
pressed to find any mention of [input_sync] on Microsoft's site. I used
Google to find links.
>
> Q: this isn't a COM question as such but i'd like your opinion on this ..
> two processes A and B are running. They each create a window. At random
> intervals they do a sendmessage to the opposite process. Isn't this a
> clear invitation to deadlock on windows? Same of course if A and B are
> threads in the same process.. right?
No, there's no deadlock. IIRC, SendMessage spins a modal loop
after posting the message to the target thread's message queue.
I believe the loop does not dispatch all messages, but it does let
through other SendMessage calls. You should ask this on a UI
group where the experts are.
>
> TIA
>
|
|
|
|
|
An email from krssagar :
I have a Connection point interface say ...(using ATL on VC++ 7)
dispinterface _MYEvents
{
properties:
methods:
[id(1), helpstring("method MyEvent")] HRESULT MyEvent([in]BSTR bstStr,[in] ISomeInterface *pInter);
};
a VC++ MFC client application registered for the event and created the
handler as :
HRESULT __stdcall MY_CPPDlg::MyEvent(CComBSTR bstStr,ISomeInterface *pInter)
{
...
...
...
pInter->Release(); //Is this LEGAL ?
}
who is resposible for releasing the interface(ISomeInterface) ?
COM or the Application ...?
When I addref the interface before firing to the client but ..for C#
and VB clients shows there is a memory leak !!
|
|
|
|
|
Reply from Bio :
Hello krssagar,
The rules of COM states that if an interface pointer is returned from a method (i.e. it is an [out] parameter, which means that the parameter would be typed something like ISomeInterface**), the method implimenter must AddRef() it and the client must later Release() it.
However, in your case, the "pInter" inerface pointer of MyEvent() is an [in] pointer which means that it is passed by value and not supplied as a reference. Hence, it should not be AddRef()'ed and the event handler should not call Release().
- Bio.
|
|
|
|
|
|
Take a simple COM coclass declaration in VC7.0 using ATL Attributes :
[
coclass,
threading("apartment"),
support_error_info("ISimpleCOMObject3"),
event_source("com"),
vi_progid("SimpleCOMObject3.SimpleCOMObject3"),
progid("SimpleCOMObject3.SimpleCOMObject3_imp.1"),
version(1.0),
uuid("E11C9A28-EFD2-45F0-979F-15C749AEB1A0"),
helpstring("SimpleCOMObject3 Class")
]
class ATL_NO_VTABLE CSimpleCOMObject3 : public ISimpleCOMObject3
{
...
...
...
__event __interface _ISimpleCOMObject3Events;
...
...
...
};
By declaring the following CSimpleCOMObject3 :
* event_source("com") attribute
* __event __interface _ISimpleCOMObject3Events
An IConnectionPointImpl is generated by the ATL Attributes Wizard.
There is thus no need to declare our own Proxy for event firing e.g. :
CProxy_ISimpleCOMObject3Events<csimplecomobject3>
from the following template :
template <class t="">
class CProxy_ISimpleCOMObject3Events : public IConnectionPointImpl<t, &diid__isimplecomobject3events,="" ccomdynamicunkarray="">
Later, if we need to refer to the collection of Connection Points clients, we refer to the following "m_vec" :
ATL::IConnectionPointImpl<csimplecomobject3, &__uuidof(_isimplecomobject3events),="" atl::ccomdynamicunkarray="">::m_vec
To help simplify using this m_vec, we can declare a synonym for the very long type name :
ATL::IConnectionPointImpl<csimplecomobject3, &__uuidof(_isimplecomobject3events),="" atl::ccomdynamicunkarray="">
by declaring the following typedef :
typedef ATL::IConnectionPointImpl<csimplecomobject3, &__uuidof(_isimplecomobject3events),="" atl::ccomdynamicunkarray=""> CATLProxy_ISimpleCOMObject3Events;
2.2 Thereafter, we can use the following code to reach the m_vec :
CATLProxy_ISimpleCOMObject3Events* pCATLProxy_ISimpleCOMObject3Events = dynamic_cast<catlproxy_isimplecomobject3events*>(this);
int nConnections = (pCATLProxy_ISimpleCOMObject3Events -> m_vec).GetSize();
...
...
...
CComPtr<iunknown> sp = (pCATLProxy_ISimpleCOMObject3Events->m_vec).GetAt(nConnectionIndex);
|
|
|
|
|
Introduction
COM is a truly excellent programming model for the development of integrating components based on interfaces. Some of the fundamental principles of COM have their roots in Object-Oriented Philosophies. It is a great platform for the realization of Object-Oriented Development and Deployment.
One of COM's major contributions to the world of Windows Development is the awareness of the concept of separation of interface from implementation. This awareness has no doubt profoundly influenced the way programmers build systems today.
An extension of this fundamental concept is the notion of : one interface, multiple implementations. By this, we mean that at runtime, a COM client can choose to instantiate an interface from one of many different concrete implementations. Each concrete implementation can be written in any programming language that supports COM component development, e.g. C++, Visual Basic, Delphi, PowerBuilder, etc.
Via COM-interop, a .NET component can also be deployed as a COM component. This implies that a COM interface implementation can be developed in a .NET language like C#. And this is what I aim to expound on and demonstrate in this article : the implementation of a COM interface in C#.
I will assume that the reader already has prior knowledge on the following :
1. COM development in general and IDL in particular.
2. C++ and ATL.
3. C# and various .NET tools like tlbimp.exe and gacutil.exe.
The following is a general outline of how I intend to go about my explanations :
1. We will briefly recap IDL and then define a simple COM interface.
2. We will develope 2 separate concrete implementations of this interface : one in C++ and the other in C#.
3. We will write a client application that will instantiate both concrete implementations and call their methods.
Emphasis will be given to the C# implemetation. I will expound on how a C# component is transformed into a COM component usable by an unmanaged client.
-- modified at 10:30 Thursday 13th October, 2005
|
|
|
|
|
A Short Refresher on IDL
The common practice in COM development is to start the definition of an interface using IDL (interface definition language). On this note, it is important to grasp the intended purpose of IDL and understand how it realizes OO principles. An IDL file is not just "another one of Microsoft's proprietary file types". It deserves deeper understanding.
Although I have stated that I wil assume the reader has prior knowledge of IDL, I will go on just a little anyway to explain here some of the more important concepts behind the IDL and the coclass (an IDL keyword) in particular :
A coclass is COM's (language independent) way of defining a class (class in the object-oriented sense).
An IDL file is what COM provides that allows developers to define such language independent object-oriented classes.
An IDL file is compiled by the MIDL compiler into a Type Library (.TLB file) which is a binary form of an IDL file meant to be processed by various language compilers (e.g. VB, VC++, Delphi, etc).
The end result of such .TLB processing is that the specific language compiler produces the language-specific constructs (VB classes for VB, C++ classes, various structs, macros and typedefs for VC++) that REPRESENT the coclass defined in the .TLB (and ultimately that which was defined in the originating .IDL).
When you look at an example coclass definition in an IDL :
coclass MyObject
{
[default] interface IMyObject;
[default, source] dispinterface _IMyObjectEvents;
};
it is declaring a COM class named MyObject which must implement an interface named IMyObject and which supports (not implement) the event interface _IMyObjectEvents.
This is conceptually equivalent to defining a C++ class like this :
class CSomeObject : public ISomeInterface
{
...
...
...
};
where ISomeInterface is a C++ virtual class.
It is up to the individual language compiler to produce whatever code (in the specific compiler's language) is necessary for its user to implement and ultimately produce a binary which can be deemed by COM to be of coclass MyObject.
Now, in languages like C++, we can use CoCreateInstance() in which we can specify the CLSID of the coclass and select the interface from that coclass that we want to use to interact with that coclass. Calling CoCreateInstance() like this :
CoCreateInstance
(
CLSID_MyObject,
NULL,
CLSCTX_INPROC_SERVER,
IID_IMyObject,
(void**)&m_pIMyObject
);
is conceptually equivalent to the following C++ code :
ISomeInterface* pISomeInterface = NULL;
pISomeInterface = new CSomeObject();
In the first case, we are saying to the COM sub-system that we want to obtain a pointer to an object that implements the IMyObject interface and we want coclass CLSID_MyObject's particular implementation of this interface.
In the second case, we are saying that we want to create an instance of a C++ class that implements the interface ISomeInterface and we are using CSomeObject as that C++ class.
Do you see the equivalence ? A coclass, then, is an object-oriented class in the COM world. The main feature of the coclass is that it is (1) binary in nature and consequently (2) programming language-independent.
-- modified at 19:18 Sunday 16th October, 2005
|
|
|
|
|