|
2008 June 20th
---------------
More Notes :
1. I noticed that if a proxy/stub DLL has been generated for an interface that is oleautomation compatible (i.e. dual or oleautomation attributes have been assigned to the interface), then the proxy/stub DLL will be used even if the Universal Marshaler (i.e. OLEAUT32.DLL) could have been used (assuming of course that the interface has been defined inside a Type Library and that the Type Library has been registered).
2. However, if that proxy/stub DLL is not registered, the Type Library will be used.
3. Note however, that re-registration and/or recompilation of the Type Library and COM Server code may be necessary to effect a switch around.
|
|
|
|
|
// Here is an example of using mem_fun1 together with bind1st()
// to call a member function of a class which has been instantiated.
// The basic objective is to be able to call the for_each() algorithm
// with the use of a member function of an object as the target function
// to be called on each item in the container.
#include <set>
#include <functional>
#include <algorithm>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class myClass
{
public :
// Note : parameter pString must not be a pointer
// nor a reference.
int DoSomethingWithString( std::string pString )
{
cout << pString.c_str() << endl;
return 0;
}
public:
void Go()
{
std::set<std::string> myStrings;
myStrings.insert("ABC");
myStrings.insert("DEF");
myStrings.insert("GHI");
std::for_each
(
myStrings.begin(),
myStrings.end(),
// Here is the challenging usage of bind1st and mem_fun1.
std::bind1st(std::mem_fun1(&myClass::DoSomethingWithString), this)
);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
myClass mc;
mc.Go();
return 0;
}
|
|
|
|
|
Another way to achieve the use of a member function in such a situation is to declare a class deriving from std::string :
class MyString : public std::string
{
public :
MyString()
{
}
MyString(const char* pstring) :
std::string(pstring)
{
}
~MyString()
{
}
void DoSomethingWithString()
{
std::cout << c_str() << std::endl;
}
};
You basically extend the std::string with a public member function named DoSomethingWithString().
Then in myClass::Go(), you use MyString instead of std::string :
void Go()
{
std::set<MyString> myStrings;
myStrings.insert("ABC");
myStrings.insert("DEF");
myStrings.insert("GHI");
std::for_each
(
myStrings.begin(),
myStrings.end(),
mem_fun_ref(&MyString::DoSomethingWithString)
);
}
Use mem_fun_ref() as the predicate for for_each(). Basically, MyString::DoSomethingWithString() wsill be called on each contained object in myStrings (which is a set of MyString objects).
|
|
|
|
|
It seems best to install CDT via the "Software Updates" facility of the eclipse IDE.
Use the following URL in a Site Bookmark in the update manager:
http://download.eclipse.org/tools/cdt/releases/eclipse3.1
To install CDT from the update site, in the Help menu select Software Updates and then Find and Install, Select Search for new features to install and click Next. Click New Remote Site to add an update with the URL provided above, and then expand the site node to reveal the available downloads.
|
|
|
|
|
Note
-----
When you build your project, you can choose a MinSize or MinDependency configuration. MinSize will generate a smaller component, since shared code will be used from Atl.dll. In this case, you must distribute Atl.dll with your component. MinDependency will generate a larger component, since all necessary code will be linked in with your component.
Note
-----
When building a Release version of a project, you can get the following link error:
LIBCMT.LIB(crt0.obj) : error LNK2001: unresolved external symbol _main
This error occurs if you are using CRT functions that require CRT startup code. The Release configurations define _ATL_MIN_CRT, which excludes CRT startup code from your EXE or DLL. To avoid this error, do one of the following:
Remove _ATL_MIN_CRT from the list of preprocessor defines to allow CRT startup code to be included. On the Project menu, click Settings. In the Settings For: drop-down list, choose Multiple Configurations. In the Select project configuration(s) to modify dialog box that appears, click the check boxes for all Release versions, and then click OK. On the C/C++ tab, choose the General category, then remove _ATL_MIN_CRT from the Preprocessor definitions edit box.
If possible, remove calls to CRT functions that require CRT startup code and use their Win32 equivalents. For example, use lstrcmp instead of strcmp. Known functions that require CRT startup code are some of the string and floating point functions.
|
|
|
|
|
Q : Why do I get a "LNK2001: unresolved external symbol _main" error or "LNK2001: unresolved external symbol _WinMain" when I try to build my application?
A : This usually happens when you create the wrong type of project for you application. In the first case, you chose "Win32 Application" when you should have selected "Win32 Console Application". On the second case, well, it's the other way.
There are two ways to fix it: (1) Create a new project of the correct type, and readd all your files too it, or (2) change the type of the current project. This can be easily accomplished. Select Project -> Settings from the menu, and go to the Link tab. There, in the edit control at the bottom, look for the /subsystem switch and change it to "/subsystem:console" or "/subsystem:windows" as appropriate.
|
|
|
|
|
Hi all,
does anybody knows if it is possible to have different behaviour of a function in template classes ?
I need to control the flow in differen cases.
I need something like this example (where I used a pseudo code format)
template <typename MYTYPE>class CMyClass{
MYTYPE var;
...
void fun(){
CString str;
//Flow contol !!
if(MYTYPE == int) str.Format("%d",var);
if(MYTYPE == float) str.Format("%f",var);
if(MYTYPE ???) str="Unable format conversion";
}
...
}
|
|
|
|
|
Hello _Russell_,
What you need is known as "explicit template specialization". Define each specialized version of "void fun()" as follows :
void CMyClass<int>::fun()
{
str.Format("%d", var);
}
void CMyClass<float>::fun()
{
str.Format("%f", var);
}
Best Regards,
Bio.
|
|
|
|
|
You also need to put template<> before explicit specializations.
--Mike--
|
|
|
|
|
Thanks friends,
It works.
But let me know if are possible other solutions, expecially if exist a way similar to the way that I used in the first message (if it exist then in some cases it can be a very fast way to write code!)
|
|
|
|
|
Yes, you can use a policy-based design as one way to solve this:
template <class T> struct format_string
{
LPCTSTR get_string() { assert(false); }
};
template<> struct format_string<int>
{
LPCTSTR get_string() { return _T("%d"); }
};
template<> struct format_string<float>
{
LPCTSTR get_string() { return _T("%f"); }
};
template<class T, class policy=format_string<T> >
class foo
{
public: void fun() { CString s = policy::get_string();}
};
--Mike--
|
|
|
|
|
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
|
|
|
|