COM interoperability - urgent help needed

M

Mike Stoker

I'm trying to use an existing COM object from within .NET
and am having problems passing a parameter than used to
be of type VARIANT.

I have a COM interface, IScanner with the following
method:

virtual HRESULT __stdcall GetOptionDetails (
/*[in]*/ long lOption,
/*[in,out]*/ VARIANT * pVarBuffer,
/*[out,retval]*/ long * plResult );

where the variant, pVarBuffer, will contain one of a
variety of structures, including:

struct IMAGE_OPTION_DETAILS
{
long lSequenceNumber;
long lGreyScaleSupported;
long lVResolution;
long lHResolution;
long lBitDepth;
};


The following code shows how the structure was previously
converted to a variant and passed to the interface:

void GetUdtRecordInfo(const TCHAR *tszName, IRecordInfo**
ppRecInfo)
{
// Use Macro for easier unicode conversion
USES_CONVERSION;

ITypeLib FAR* pITypeLib;
ITypeInfo FAR* pITypeInfo;

HRESULT hr = LoadRegTypeLib(LIBID_PSCLASSICLib,
1, 0,
GetUserDefaultLCID
(), &pITypeLib);

if (hr != S_OK)
THROW_ERROR("Failed to load type
library");


// Retreive the IRecordInfo from the ITypeInfo
interface for the first (and only) occurance
// of the type in the type library
USHORT nFound = 1; // number of occurances
to look for
MEMBERID mID[1]; // array to store the
MEMBERID of the type. Must be same size as nFound

hr = pITypeLib->FindName(T2OLE(tszName), 0,
&pITypeInfo, mID, &nFound);
if (hr != S_OK)
THROW_ERROR("Failed to find the name of
UDT.");

hr = GetRecordInfoFromTypeInfo(pITypeInfo,
ppRecInfo);
if (hr != S_OK)
THROW_ERROR("Failed to get the Record
Info of UDT");


// Release interfaces
pITypeInfo->Release();
pITypeLib->Release();
}


void ConstructRecordVariant(IRecordInfo* pRecInfo,
LPVARIANT pVariant, void* pStruct)
{
VariantInit(pVariant);
V_VT(pVariant) = VT_RECORD | VT_BYREF;
V_RECORD(pVariant) = pStruct;
pVariant->pRecInfo = pRecInfo;
}

int _tmain()
{
IMAGE_OPTION_DETAILS details;

VARIANT var;
IRecordInfo* pRecordInfo = NULL;

CString sTypeName = "IMAGE_OPTION_DETAILS";
void* pStruct = &details;

// Construct the VARIANT data structures for the
detail, in and out data.
GetUdtRecordInfo(sTypeName, &pRecordInfo);

ConstructRecordVariant(pRecordInfo, &var,
pStruct);

// now we make the call to the COM interface
HRESULT = pIScanner->GetOptionDetails
(IMAGE_FRONT, &var);

return 0;
}

In DotNet, the COM object is wrapped into a class with
the above method converted to:

public int GetOptionDetails(int lOption, ref object
pVarBuffer);

My question is how do I pass the converted version of the
above structure to this method? I tried the obvious

ScannerClass * scanner = new ScannerClass();

IMAGE_OPTION_DETAILS details;
Object* obj = __box(details);

scanner->GetOptionDetails(
SCANNER_OPTIONS::IMAGE_FRONT,
&obj);


but this failed with:


"A first chance exception of
type 'System.ArgumentException' occurred in PSTest.exe"

"Additional information: The specified record cannot be
mapped to a managed value class."


Any help would be much appreciated!

Mike.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top