Consider this registered type library in a DLL:
[uuid(…), version(1.0)]
library structLib
{
importlib("stdole2.tlb");
[uuid(…)]
typedef struct MyStruct
{
BSTR m_sStr;
} MyStruct;
};
In vb6 I can reference this type library and use the UDT / struct in a compiled exe (simple form with a button), named a.exe:
Private Sub Command1_Click()
Dim obj As structLib.MyStruct
obj.m_sStr = "Hello"
MsgBox obj.m_sStr
End Sub
When I remove the struct from the type library and recompile it, the previously compiled a.exe still works, even though the struct definition is no longer present. I assume this succeeds because the definition is embedded into the executable during the vb6 compilation process.
However, things work differently when I compile the following vb6 code against the unmodified type library (struct included) into a new executable, named b.exe:
Private Sub Command1_Click()
Dim obj As structLib.MyStruct
obj.m_sStr = "Hello"
MsgBox obj.m_sStr
Dim vt as Variant
vt = obj
MsgBox vt.m_sStr
End Sub
Notice the assignment of the struct to a Variant
.
When I remove the struct definition from the type library once again, recompile it, and try to run the previously compiled b.exe, the program silently fails as the form won't even show up. At minimum, I expected
Variant
.For the record, I have tried to reproduce this behavior in C++:
structLib::MyStruct obj;
obj.m_sStr = SysAllocString(L"Hello");
MessageBox(GetActiveWindow(), obj.m_sStr, obj.m_sStr, MB_OK);
ATL::CComVariant vtRec;
ATL::CComPtr<IRecordInfo> piRecInfo;
HRESULT hr = GetRecordInfoFromGuids(__uuidof(structLib::__structLib), 1, 0, 0, __uuidof(structLib::MyStruct), &piRecInfo);
vtRec.pRecInfo = piRecInfo;
vtRec.pvRecord = &obj;
PVOID pvItem = vtRec.pvRecord;
CComVariant vtStr;
hr = piRecInfo->GetField(pvItem, L"m_sStr", &vtStr);
MessageBox(GetActiveWindow(), vtStr.bstrVal, vtStr.bstrVal, MB_OK);
Here, the C++ client runs and GetRecordInfoFromGuids()
correctly returns
0x8002802b (Element not found)
when the struct definition is missing in the type library.
Is this behavior in vb6 by design? What's the cause? And is it possible to start the vb6 executable and catch error information, even when extracting type information of a referenced struct fails?
Is this behavior in vb6 by design?
I don't think so.
What's the cause?
When you assign a IDL structure to a VARIANT, the [uuid] attribute is intrinsically used. As it doesn't exist anymore, you get an exception.
That's what you do when calling GetRecordInfoFromGuids
in C++, you provide explicitely the uuid of the IDL structure __uuidof(structLib::MyStruct)
.
And is it possible to start the executable even when extracting type information of a referenced struct fails?
I see 2 possibilities to achieve this goal:
User contributions licensed under CC BY-SA 3.0