I am trying to import VB6's VBRUN type library into a Visual C++ 2017 header file, but it is failing due to a missing dependency.
Visual C++ reports
"error C4772: #import referenced a type from a missing type library;
'missing_type' used as a placeholder"
Viewing the file with OLE View reveals the problem is with the DataFormat property (DataFormat([out, retval] --<GetRefTypeInfo failed>** Return)).
The missing dependency would appear to be stdDataFormat: which type library does stdDataFormat reside in and why is it missing? (My operating system is Windows 10 Enterprise, 21H1.) Did I miss a selection when installing Visual Studio 6?
This addresses the first part of the question, how to find the typelib (TLB) containing a given interface or class.
Assuming you have no preconception about the TLB / DLL hosting a given COM interface or class you can find it by a couple of registry searches, assuming the type in question actually has been registered.
I started off in HKEY_CLASSES_ROOT with a search for data values = stdDataFormat. This lead to:
[HKEY_CLASSES_ROOT\MSSTDFMT.StdDataFormat]
#="StdDataFormat Object"
[HKEY_CLASSES_ROOT\MSSTDFMT.StdDataFormat\CLSID]
#="{6D835690-900B-11D0-9484-00A0C91110ED}"
Now armed with the CLSID GUID of 6D835690-900B-11D0-9484-00A0C91110ED, search for that value, finding:
HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{6D835690-900B-11D0-9484-00A0C91110ED
of which its important sub-element for our purposes is:
[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{6D835690-900B-11D0-9484-00A0C91110ED}\InprocServer32]
#="c:\\windows\\SysWow64\\msstdfmt.dll"
...
The InprocServer32 value was the main thing I wanted to find; it tells you the DLL - which is c:\windows\SysWow64\msstdfmt.dll (on my PC - but this should be typical).
Opening msstdfmt.dll in OLEView (or OLEViewDotNet) confirms this; the decompiled IDL from the TLB in that DLL contains:
[
uuid(6D835690-900B-11D0-9484-00A0C91110ED),
helpstring("StdDataFormat Object"),
helpcontext(0x00066b5f)
]
coclass StdDataFormat {
[default] interface IStdDataFormatDisp;
[default, source] dispinterface IStdDataFormatEvents;
};
So msstdfmt.dll should be the missing dependency.
If you did suspect this DLL to begin with, then obviously its a lot quicker to just load it in OLEView and check. But in many cases that won't be obvious when you're starting out.
As for the second part of the question - why is this dependency missing - maybe it would help if you added the relevant section of your code / includes?
Related
I want to read the code, more like variable and function names since I can catch values with CheatEngine, of an exe file. I got information about the file from Exeinfo PE which told me
"Microsoft Visual C++ ver. 8.0 / Visual Studio 2005 [ Debug:02 ]"
a screencap from Exeinfo PE
I have identified the code in assembly in some ways using IDA, radare2 and CheatEngine's Memory Table.
I don't know what else I can list so ask me if you need further details. thank you very much.
I believe your question is:
How to view the function and variable names of a compiled program?
When compiled in debug mode, some information will be present in the binary. If there is a .pdb it will contain additional debug information as well.
But when compiled in release mode, C++ itself does not compile in a way in which it retains any variable names or function names or other identifying information such as this.
The only exception to this is RTTI or Run Time Type Information. RTTI you can think of like symbol names for virtual functions. Microsoft Visual C++ predominantly does this but other compilers can as well. RTTI can be parsed and it will give you the class names in relation to the their virtual function tables. If the class does not have virtual functions, you will not find RTTI for it.
The best tool I know of for parsing RTTI is Class Informer which is a plugin for IDA Pro.
dllmain.cpp(16): warning C4447: 'main' signature found without threading mode
l. Consider using 'int main(Platform::Array<Platform::String^>^ args)'.
Above is a warning I got from building a Windows Store App DLL project. I didn't change anything in that default dllmain.cpp file except for including my own version of pch.
The documentation for this warning (along with many VS2012 errors/warnings) is nowhere to be found on MSDN and here is the only relevant link I can find:
http://social.msdn.microsoft.com/Forums/en-US/vssetup/thread/6daa9587-fe54-4e84-a8b9-0e5c52c2f6e8/
and the op there didn't get an answer.
If anyone knows what it means and how to fix it, it would be great!
As far as I can tell, you can safely ignore the warning. The compiler cribs when it sees a Win32-style DllMain being compiled using the /ZW flag (Consume Windows Runtime Extensions). However, the function gets called as you'd normally expect.
Alternatively, you can work around the warning by compiling dllmain.cpp without /ZW. You might need to adjust the PCH settings for this to properly work. This is the path taken by the DLL (Windows Store apps) C++/CX project template in Visual Studio.
Incidentally, the reason you do not get the warning when you're trying to build a Windows Runtime Component project (which builds everything using /ZW) is that a Windows Runtime Component doesn't declare a DllMain. This is not to say that it can't; it just picks up the dummy DllMain that the CRT defines (which basically turns off per-thread initialization and reports success).
I have a strange warning in some code I'm trying to maintain. I'm currently testing it out in its current environment (Visual C++ 6.0, yes, I know, ancient) before moving it up to a more modern VC++ version. I don't understand this warning, and what effect it might be having on the EXE target I'm compiling. During compilation I get this output in the build tab:
Processing C:\OSDK\Libraries\PSDll\OSDKDefs.idl
OSDKDefs.idl
.\Server\Interfaces\InterfaceDef.idl(109) : warning MIDL2346 : the specified lcid is different from previous specification
Compiling...
The above IDL file is a slightly hacked up version of an IDL file provided by a vendor which no longer provides any support for the above libraries. I believe that this comment in the IDL file was added by a former maintainer of this project, who has hacked this IDL file. My question is, I can make the warning go away by changing the lcid back to the value in the comment, possibly reintroducing some unwanted problem that the original modifier of this idl file wanted to avoid. What is an lcid and what would the difference between the behaviour with lcid(0x409) and lcid(0x09) be? A single bit with value 0x400 hex is being toggled, but what does that bit do?
The line that is causing the warning is marked and commented below, formerly lcid(0x409)
changed to lcid(0x09) for "compatibility" with some kind of test tool that this vendor provides for their DCOM/COM code, the tool is mentioned in the comments below.
//
// Component and type library descriptions
//
[
uuid(bbf92ab1-5031-40c2-864d-1c301f51d0ce),
// mvs04042000 - Changed back the lcid from 0x409 to 0x09. Else we have problems
// connecting from the PowerTool.
lcid(0x09), /// <<----- WARNING HERE
version(7.16),
helpfile("OsdkTlb.hlp"),
helpstring("OPC Server 7.16 Library"),
helpcontext(0x00000010)
]
library ED3Drv
{
importlib("stdole32.tlb");
[
uuid(b66ac2ca-d99e-4319-8fc0-08c0b65e65df),
appobject
]
coclass ED3Server
{
[default] interface IED3Driver;
interface IDriver;
interface IDriverMessage;
interface IDataScopeConnect;
interface IDispatch;
[source] interface IDataScopeSink;
};
};
The IDL above is part of a toolkit that was designed to help people write C++ DCOM clients and servers that match a specification called OPC (OLE for Process Controls).
lcid is LocaleID. 0x409 equals to 1033, which is English (United States). 0x09 is not a valid locale id value.
See http://msdn.microsoft.com/en-us/library/ms912047(v=winembedded.10).aspx for a complete list of valid values.
I have a new project where I cannot use boost::format. I get a compiler error complaining that boost's override of a virtual function, ~basic_altstringbuf, lacks a "throw()". Even the most trivial attempt to use boost::format does that.
I have other projects where it works fine. I have verified that the new project uses the same include-paths for boost, and for the VC++ includes. All the projects have "Enable C++ Exceptions" set to Yes. The only explanation I can come up with is that the projects that work have some #DEFINE or some setting that disables those vile exception specs in the std:: include-files. But I have no idea what or where it might be. Any ideas?
Error 1 error C2694: 'boost::io::basic_altstringbuf::~basic_altstringbuf(void)': overriding virtual function has less restrictive exception specification than base class virtual member function 'std::basic_streambuf<_Elem,_Traits>::~basic_streambuf(void) throw()
EDIT: Corollary question: Is there a Properties-item in VS++ 2012 that will cause the std:: header files to be included without exception-specs? - short of turning off exceptions, that is?
At the request of the original owner of the green check-mark, I am submitting this summary.
The bugs are on the Microsoft side, in header-files for C++ standard library interfaces, and in the VC++ compiler when "Disable Language Extensions" is NOT set. The header files contain exception-specifications that the standard does not call for. When "language extensions" are not enabled, the compiler accepts invalid code. I have filed a bug report.
Boost could work around the problem in this specific case by adding seven characters to a nested include-file, i.e. "throw()" at line 65 in alt_sstream_impl.hpp. I filed a report with boost also, although I made it clear that the bug is not in their code. I am just suggesting a workaround.
All the tedious details are in the two reports linked above.
Check the preprocessor defines.
You might turn on and inspect verbose logging to see the exact flags that are passed to cl.exe
You could keep the preprocessed source and compare the version from the old (working) project with the new (failing) project.
My gut says, something else is being #defined/passed using -D in the old project that is not being defined in the new project, of differently (think of WINVER type macros)
See new answer posted: VC++ 2012 and Boost incompatibility - `throw()` specifications in library headers
EDIT by OP, Jive Dadson - It turned out to be /Za, which enables/disables "Microsoft language extensions." It is the contention of Visual Studio that the C++ standard requires that a program shall not compile if it has a virtual function override that is less restrictive in the "throw()" category than the function it overrides. Boost has a class that derives from basic_streambuf, and has a virtual destructor that lacks "throw()". The original destructor has that evil festoon. My new project will compile boost::format if I turn MS language extensions ON.
So the question becomes, who is wrong, and how? Is it standard-complying to put throw() on that destructor or not? Is the desired behavior (desired by me, that is) actually an "extension"? I seem to recall that MS considered some standard C++11 features to be "extensions," but I am not sure I remember correctly. Anyway, I will leave it to the boosters to decide, if they are interested. https://svn.boost.org/trac/boost/ticket/7477
I am trying to build an old version of an application which consists of VC++ projects that were written in Visual Studio 2003.
My OS is Windows 7 Enterprise (64-bit).
When I try and build the solution I get the following errors:
error C4772: #import referenced a type from a missing type library; '__missing_type__' used as a placeholder
fatal error C1084: Cannot read type library file: 'Smegui.tlb': Error loading type library/DLL.
They both complain about the following import statement:
#import "Smegui.tlb" no_implementation
This is not a case of the file path being incorrect as renaming the Smegui.tlb file causes the compiler to throw another error saying it cannot find the library.
Smegui is from another application that this one depends on. I thought perhaps I was missing a dll but there is no such thing as Smegui.dll.
All I know about .tlb files is that they are a type library and you can create them from an assembly using tlbexp.exe or regasm.exe (the later also registers the assembly with COM)
There is also an Apache Ant build script which uses a custom task to invoke devenv.com to build the projects. This is the same script that the build server originally used to build the application. It gives me the same errors when I try and run it.
The strangest thing about this is that I knew it ought to work seeing as it is all freshly checked out from subversion. I tried many different combinations of admin vs user elevation, VS vs Ant build, cleaning, release.
I have got it to build successfully about 5 times but the build seems to be non-deterministic.
If anyone can shed some light on how this tlb stuff even works or what this error might mean I would greatly appreciate it.
I found a far more reliable solution: open the tlb with oleview.exe and then close it.
Not sure what this actually does but it works every time.
I think oleview is actually one of the samples included with Visual Studio but I haven't had the time to debug it and see what it is doing.
I ran into this error because one type library was trying to load a dependent type library, which it could not find. Even though the dependent type library was in the same directory, and even though that directory was in the searchable path, the compiler would error loading the first type library, but not mention the dependent type library in the error.
To find the pseudo-missing type library, I ran Process Monitor (procman64.exe) during the compile. This showed that after the reported type library had successfully loaded, a dependent type library could not be found. It even showed all of the places that it was looking for the dependent type library, none of which were where it should have been looking (e.g.: ).
The fix was to add a <PreBuildEvent> to the project to copy the dependent .tlb file to one of the directories that was actually being searched.
<PreBuildEvent>
<Command>copy /Y ..\Lib\Interop\CWSpeechRecLib.tlb .\</Command>
</PreBuildEvent>
http://msdn.microsoft.com/en-us/library/sce74ah7%28VS.71%29.aspx
smegui.tlb is referencing some other tlb that the compiler can't find. If you have the .idl for smegui you might be able to figure out what the other is. I suspect the missing tlb is something that original build machine had registered but that your machine doesn't have registered.
A type library is a binary description of a set of interfaces, coclasses and enums. They're usually generated for COM components, in the case of tlbexp and regasm the tlb is created from the assembly metadata. For native COM components they are usually generated from an idl (Interface Description Language) file by the midl tool.
Edit:
I just noticed you're on x64 Windows. Are you building the project with a new version of Visual Studio? If so, are you targeting x86 or x64? If the latter, it may simply be a 32bit component that the compiler can't find (or less likely, a x64 component the x86 compiler can't find if you are targeting x86), for WOW64 the registry is virtualized for x86 vs. x64 applications.
Well I finally found out why I managed to get it to build sometimes and not others... sort of.
So long as I ran the build script with elevated administrator permissions and let that get as far as it could until that error occurred, then run the build script again as a protected administrator succeeded. Those steps must be done in that exact order with no other steps in between. If I try build in Visual Studio it does not work (although I did get it to succeed once). Probably some kind of virtualisation issue although it still doesn't quite make sense.
Well I don't need help on this any more and I know it's probably impossible to fully answer this question without knowing exactly what the build is doing. However if anyone does have any more thoughts I would happily receive them.
Cheers,
Steiny