Feeds:
Posts
Comments

Archive for January, 2006

I got this tip from my friend, Rama Krishna Vavilala – who’s virtually a total expert in anything Win32, from SDK to COM to .NET! Thanks Rama!

By default, the CCW will convert your managed object’s methods so that the return type is an out parameter of the COM method. For example, if your managed method was :-

bool IsTrue(String^);

…then your CCW method will be :-

HRESULT IsTrue ([in] BSTR,
    [out,retval] unsigned char*);

Pretty annoying to have to check the HRESULT and to have to pass a pointer to the expected return type. Well, you can force the method to preserve its signature. You just need to apply the MethodImplAttribute to the method with MethodImplOptions::PreserveSig. Now your CCW method will become :-

unsigned char IsTrue([in] BSTR);

There, that’s much better now! Of course, to do this, you need to have access to the managed library source code, and your scenario should permit you to change the source code this way. Sometimes it may not be all that convenient to do so. But when you can, it’s good to know that there’s a way to do so.

Read Full Post »

I was working on an app that uses CCW to access a managed library. One of the methods in the library returns an array<String^>^. The COM version of this method will have a SAFEARRAY** as the [out,retval] parameter. Not having a lot of COM experience, I was pretty surprised to find how little documentation there is on MSDN or any where else for that matter on using a SAFEARRAY. All I wanted to do was to enumerate the returned array. Eventually it turned out to be pretty easy. For the interested few, here’s what you need to do.

SAFEARRAY* pSA= NULL;
if(SUCCEEDED(pXXXX->GetXXXX(XXXXid, &pSA)))
{
    long lbound = 0, ubound = 0;

    SafeArrayGetLBound (pSA, 1, &lbound);
    SafeArrayGetUBound (pSA, 1, &ubound);

    BSTR* s = NULL;
    SafeArrayAccessData(pSA, (void**) &s);
    wcout << "XXXXXXXXXXXX" << endl;
    for(long i=lbound; i<=ubound; i++)
    {
        wcout << "\t" << s[i] << endl;
    }
    SafeArrayUnaccessData(pSA);
    SafeArrayDestroy (pSA);
}

Read Full Post »

CAutoNativePtr is a managed template class that I wrote, which acts as a smart pointer for using native objects in managed code, and it’s been posted on Code Project.

CAutoNativePtr – A managed smart pointer for using native objects in managed code

The class manages a smart pointer, which will automatically free the native resource when it falls out of scope or the containing managed object is finalized during garbage collection. The copy constructors and assignment operators transfer ownership, which means that only one CAutoNativePtr can own a specific native object at any time (unless you write buggy code that directly overrides this rule). Take a look at the article for more details and to download the class.

Read Full Post »

Holy cow! I very nearly wrote some messed up code a few minutes ago. I was writing this disposable class, and I wanted to call the finalizer from my destructor, to avoid code duplication. Guess what I did first! Man, I really was stupid! Here goes.

~MyType()
{
    !MyType();
}

And you know what that code does, don’t you? It constructs a new object and calls the logical Not operator on it! :oops:

This was what I meant to do.

~MyType()
{
    this->!MyType();
}

Geez! That’s the sort of bug that could easily have slipped past me, and I wouldn’t have known for a long time. :hmmm:

Read Full Post »

gcnew T vs gcnew T()

I was asked recently, why I always do gcnew T() when gcnew T produces the exact same MSIL. Here’s why. In standard C++, new T and new T() are not the same. The latter version zeroes out the memory before calling the constructor, so if you haven’t initialized a member variable, it’s zero initialized by default. To be safe, I always did new T() even though it incurred some extra lines of code. To be consistent in syntax, I chose to do the same with gcnew too, even though for both cases, the CLR zeroes out the memory before invoking a call to the constructor.

[MOD]Just a note to add that the difference is applicable only to POD types. See my comment on this.[/MOD]

Read Full Post »

The following code will not compile :-

#include <windows.h>
#include <wabdefs.h>

int main()
{
    return 0;
}

You’ll get a compiler error (C2371) saying that you are redefining WCHAR. The problem is that wabdefs.h defines WCHAR as a typedef for WORD, while winnt.h defines WCHAR as a typedef for wchar_t. In VC++ 2005, /Zc:wchar_t is on by default, which means that wchar_t is a totally different type from unsigned short, as older compilers would expect it to be. This is a definition clash and the bug is in winnt.h, and it’s amazing that the PSDK team didn’t pick this one. If you are an app developer, you can modify your local copy of winnt.h, but if you are a developer who works on a source code library, you are going to have some angry clients when you tell them that they need to edit their winnt.h to get the library to compile. This bug is a total pain in the ass and until the PSDK team fixes winnt.h, there’s no real workaround :grrr:

Read Full Post »

I was just going through my Code Project article on Function overriding in C++/CLI, and I noticed how the code snippets in the article indicated that if you don’t specify new or override on a derived class virtual function, override is assumed. Well, I was using an early Alpha compiler when I wrote that article and now, in the RTM version of the compiler, the compiler will not let you do that. For virtual functions of ref types, overriding is always explicit.

ref class Base
{
public:
    virtual void F(){}
};

ref class Derived : Base
{
public:
    virtual void F() {} // <-- error C4485
};

The right way would be to do one of the following :-

virtual void F() override {}
// or
virtual void F() new {} 

Read Full Post »

The first time it happened to me, I was totally stunned I tell you. There I was, driving happily when it started snowing, and when I used my wipers, the glass got all cloudy and so I used the windshield (or wiper) fluid, and guess what! The damn liquid froze on the windshield, despite my having the defroster on at full heat! I had to drive with partial visibility and luckily, since it was Christmas time, the roads weren’t all that busy! Anyway, last week, we went and bought a wiper fluid that stays liquid up to -45 degrees C! Man, the things you encounter when you move to a foreign climate are awesome!

Read Full Post »

Follow

Get every new post delivered to your Inbox.