tags:

views:

497

answers:

3

I am writing a C++ DLL that is called by an external program.

1.) I take an array of strings (as char *var) as an argument from this program.

2.) I want to iterate through this array and call a COM function on each element of the string array. The COM function must take a BSTR:

DLL_EXPORT(void) runUnitModel(char *rateMaterialTypeNames) {

    HRESULT hr = CoInitialize(NULL);

    // Create the interface pointer.
    IUnitModelPtr pIUnit(__uuidof(BlastFurnaceUnitModel));

    pIUnit->initialiseUnitModel();

    int i;
    for(i=0; i < sizeOfPortRatesArray; i++)
            pIUnit->createPort(SysAllocString(BSTR((const char *)rateMaterialTypeNames[i])));

I think its the SysAllocString(BSTR((const char *)rateMaterialTypeNames[i])) bit that is giving me problems. I get an access violation when the programs runs.

Is this the right way to access the value of the rateMaterialTypeName at i? Note I am expecting something like "IronOre" as the value at i, not a single character.

+3  A: 

If the parameter to the function rateMaterialTypeNames is a string, then

rateMaterialTypeNames[i]

is a character and not a string. You should use just the parameter name itself.

In addition, casts in general are bad. The conversion to a BSTR is a big flag. The parameter type for SysAllocString is

const OLECHAR*

which for 32-bit compilers is a wide character. So this will definitely fail because the actual parameter is a char*.

What the code needs is a conversion of narrow string to a wide string.

const OLECHAR* pOleChar = A2COLE( *pChar );
BSTR str = SysAllocString( pOleChar );
// do something with the 'str'
SysFreeString( str ); // need to cleanup the allocated BSTR
Tommy Hui
+4  A: 

Because a variable holding a C string is just a pointer to the first element (a char*), in order to pass an array of C strings, the parameter to your function should be a char**:

DLL_EXPORT(void) runUnitModel(char **rateMaterialTypeNames)

This way, when you evaluate rateMaterialTypeNames[i], the result will be a char*, which is the parameter type you need to pass to SysAllocString().

Added note: you will also need to convert the strings to wide chars at some point, as Tommy Hui's answer points out.

Matthew Xavier
+1 for spotting the problem with the parameter. See my answer for an easy - but ATL specific - way to create the BStr
Binary Worrier
+5  A: 

If you're using Microsofts ATL, you can use the CComBSTR class. It will accept a char* and create a BSTR from it, also, you don't need to worry about deleting the BSTR, all that happens in the dtor for CComBSTR.

Also, see Matthew Xaviers answer, it doesn't look like you're passing your array of strings into that function properly.

Hope this helps

Binary Worrier