Welcome, guest | Sign In | My Account | Store | Cart

Two items:

  1. Python script that defines and registers a factory COM class and another COM class that can be instantiated by the factory.
  2. (Ugly) VC++ code that exercises the factory and then the object returned by the factory.

The Python COM object returned by the factory provides rudimentary stemming; ie, it removes any final 's' from a word that is passed to it and returns the truncated word as its result.

Python, 152 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# Python code
from win32com . server . register import UseCommandLine
from win32api import MessageBox
from win32com . client import Dispatch
from win32ui import MessageBox

class StemmerFactory :
    _reg_clsid_ = "{602D10EB-426C-4D6F-A4DF-C05572EB780B}"
    _reg_desc_ = "LangTech Stemmer"
    _reg_progid_ = "LangTech.Stemmer"
    _public_methods_ = [ 'new' ]

    def new ( self, scriptFile ) :
        self . scriptFile = scriptFile
        stemmer = Dispatch ( "LangTech.Stemmer.Product" )
        return stemmer

class Stemmer :
    _reg_clsid_ = "{B306454A-CAE6-4A74-ACAD-0BB11EF256DD}"
    _reg_desc_ = "LangTech Stemmer Product"
    _reg_progid_ = "LangTech.Stemmer.Product"
    _public_methods_ = [ 'stemWord' ]

    def stemWord ( self, word ) :
        # extremely simple stemming: if the word ends in 's' then drop the 's'
        if word [ -1 ] == "s":
            return word [ : -1 ]
        else:
            return word

if __name__ == '__main__' :
    UseCommandLine ( StemmerFactory )
    UseCommandLine ( Stemmer )

#----------------------------------------
#
# C++

#include <comdef.h>
#include <initguid.h>

DEFINE_GUID(CLSID_StemmerFactory,
  0x602D10EB, 0x426C, 0x4D6F, 0xA4, 0xDF, 0xC0, 0x55, 0x72, 0xEB, 0x78, 0x0B);

DISPID rgDispId ;
OLECHAR * rgszNames [ ] = { OLESTR ( "new" ) };
DISPPARAMS DispParams;
VARIANT VarResult;
EXCEPINFO excepinfo;
UINT uArgErr;
VARIANTARG * pvarg = NULL;
_bstr_t stemmedWord;
HRESULT hr;
IDispatch * stemmerFactory;
IDispatch * stemmer;

if ( FAILED ( hr = CoInitialize ( NULL ) ) ) {
    MessageBox ( 0, "CoInitialize failure", "Fault", MB_OK );
    break;
}

if ( FAILED ( hr = CoCreateInstance (
    CLSID_StemmerFactory,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_IDispatch,
    ( LPVOID * ) & stemmerFactory ) ) ) {
    MessageBox ( 0, "CoCreateInstance failure", "Fault", MB_OK );
    break;
}

if ( FAILED ( hr = stemmerFactory -> GetIDsOfNames (
    IID_NULL,
    rgszNames,
    1,
    LOCALE_SYSTEM_DEFAULT,
    & rgDispId
    ) ) ) {
    MessageBox ( 0, "GetIDsOfNames failure", "Fault", MB_OK );
    break;
}

DispParams.cArgs = 1;
DispParams.cNamedArgs = 0;
DispParams.rgdispidNamedArgs = 0;

pvarg = new VARIANTARG [ DispParams . cArgs ];
if ( pvarg == NULL ) {
    MessageBox ( 0, "Insufficient 1st memory", "Fault", MB_OK );
    break;
}

pvarg -> vt = VT_BSTR;
pvarg -> bstrVal = SysAllocString ( L"engRules.pl" );

DispParams.rgvarg = pvarg;

if ( FAILED ( hr = stemmerFactory -> Invoke (
    rgDispId,
    IID_NULL,
    LOCALE_SYSTEM_DEFAULT,
    DISPATCH_METHOD,
    & DispParams,
    & VarResult,
    & excepinfo,
    & uArgErr
    ) ) ) {
    MessageBox ( 0, "1st Invoke failure", "Fault", MB_OK );
    break;
}

delete ( pvarg );

stemmer = VarResult.pdispVal;

pvarg = new VARIANTARG [ DispParams . cArgs ];
if ( pvarg == NULL ) {
    MessageBox ( 0, "Insufficient 2nd memory", "Fault", MB_OK );
    break;
}

pvarg -> vt = VT_BSTR;
pvarg -> bstrVal = SysAllocString ( L"cats" );

DispParams.rgvarg = pvarg;

if ( FAILED ( hr = stemmer -> Invoke (
    rgDispId,
    IID_NULL,
    LOCALE_SYSTEM_DEFAULT,
    DISPATCH_METHOD,
    & DispParams,
    & VarResult,
    & excepinfo,
    & uArgErr
    ) ) ) {
    MessageBox ( 0, "2nd Invoke failure", "Fault", MB_OK );
    break;
}

delete ( pvarg );

stemmedWord = VarResult.bstrVal;

MessageBox (
    0,
    ( const char * ) stemmedWord,
    "Resulting Stemmed Word",
    MB_OK
    );

CoUninitialize ( );

Even moderately able C++ programmers will find my code ugly. (Please feel free to suggest improvements.)

Some tasks are much easier to code in Python (!), and this recipe shows the basics of how to use COM to connect Python to VC++.

Created by Bill Bell on Sat, 27 Jul 2002 (PSF)
Python recipes (4591)
Bill Bell's recipes (16)

Required Modules

  • (none specified)

Other Information and Tasks