I have a dll called hecom32.dll. I want to use this in my application. I acll the following:
#import "hecom32.dll"
And I get the following error:
enter Error 1 error C1083: Cannot open type library file: 'c:\users\dvargo\documents\visual studio 2010\projects\johnny\johnny\hecom32.dll': Error loading type library/DLL. c:\users\dvargo\documents\visual studio 2010\projects\johnny\johnny\johnny.cpp 6 1 Johnny
Obviously it cant add it. I am not sure however to determine what is wrong with it. Is there some way that I can analyze the file to see why it cant be imported. Is there a different way to use the functions in the dll?
I am using Visual Studio 2010
This will only work properly if hecom32.dll implements a COM server and has the type library embedded as a resource. You can check that with File + Open + File, select the dll. You'll see the resources listed, there should be one labeled "TYPELIB" with a resource ID of 1 if you open the node.
Surely that's missing, the error message says as much. Embedding a type library is a convention, it isn't required. Just keeping it separate as a .tlb file is possible as well. And of course, it might not be a COM server at all. You can see that by running Dumpbin.exe /exports on the dll. A COM server has at least an export named "DllGetClassObject".
If none of this pans out then you'd better contact the owner of the DLL and ask for help on how to use it properly. Which typically requires having a .h file with the declarations of the exported functions and a .lib file so you can link it.
Related
I'm reusing a code I wrote couple years ago on a different version of Visual Studio, now Im trying to do it in VS 2017. The code aims to connect different applications using server-client arrangement.I'm accessing the .tlb of one application but I cannot establish the connection (either error of non-accessible .tlh or just no identification of different application methods/properties) , among 254 others.
The question is similar to this one: Import .TLB file gives "cannot open source file x.tlh"
I have tried adding the .tlb file in additional library directories but even when the error disappears, the code still doesnot recognize many methods that were fine before. #import statement shows no errors, yet the generated .tlh file has the following error:
forward declaration of enum type is nonstandard
Hence, It doesnot compile
Other issues also appeared, such as this:
no instance of function template "IID_PPV_ARGS_Helper" matches the argument list
for this line:
HRESULT hr = hyStream->QueryInterface(IID_PPV_ARGS(&Strm));
Now, the whole project was running seamlessly back then. I copied three classes with their headers to a new project, so maybe dependencies are the source of errors? Should I add .tlb file in library dependencies of the project?
Any comment is highly appreciated..
I'm trying to conditionally use (if available) the function PathCchAppend. I have got the function signature from header pathcch.h. However, when I try to get the address of function from SHLWAPI.DLL, it fails:
auto pca = GetProcAddress(GetModuleHandle(L"shlwapi.dll"), "PathCchAppend");
Using Depends, I saw that this function does not exist in this DLL (I'm on Windows 10). There doesn't exist any pathcch.dll and hence cannot load it either.
In which DLL this function is placed?
EDIT:
Thanks to the answers. Here I found the names of DLL as is mentioned in the answers below:
https://learn.microsoft.com/en-us/windows/win32/apiindex/windows-81-api-sets
You can use the DUMPBIN tool to extract this information from the .lib file:
dumpbin /headers /path/to/pathcch.lib
You then need to sift through the output to find the function in question. For instance, this is the output for an x64 version of the lib file:
Version : 0
Machine : 8664 (x64)
TimeDateStamp: FFFFFFFF Sun Feb 07 06:28:15 2106
SizeOfData : 0000002E
DLL name : api-ms-win-core-path-l1-1-0.dll
Symbol name : PathCchAppend
Type : code
Name type : name
Hint : 5
Name : PathCchAppend
Regarding the comments about backwards and forwards compatibility of hard coding this DLL name, the .lib file hard codes the DLL name. So if you link to the function using the .lib file, then you are hard coding a dependency to that DLL. This binds Microsoft into a contract to continue exporting this function from this DLL in future releases of Windows. And so it is no more or less safe to link explicitly using LoadLibrary/GetProcAddress than it is to link implicitly using the .lib file from the SDK.
api-ms-win-core-path-l1-1-0.dll is not an actual DLL nor file on disk, instead it's some virtual name only, so that the loader is able to map requests to some disk on the file in the end. The extension DLL is used by convention or as a system requirement by the loader only, but doesn't imply any file as well.
You can use an API set name in the context of a loader operation such as LoadLibrary or P/Invoke instead of a DLL module name to ensure a correct route to the implementation no matter where the API is actually implemented on the current device. However, when you do this you must append the string .dll at the end of the contract name. This is a requirement of the loader to function properly, and is not considered actually a part of the contract name. Although contract names appear similar to DLL names in this context, they are fundamentally different from DLL module names and do not directly refer to a file on disk.
https://learn.microsoft.com/en-us/windows/win32/apiindex/windows-apisets#api-set-contract-names
So the real answer to the question is KernelBase.dll. That is important for use cases like mine, where I need to create a lib file based on an actual DLL, which is only possible with KernelBase.dll. MS maintains some additional docs making the underlying file of some API set available as well.
I'm new C++, I have a dll file called DiceInvaders.dll, in my project, I need to use this library, I'm using visual c++ 2010, I set the Linker Input as DiceInvaders.lib and DiceInvaders.dll, I also copied this dll file to my porject directory, I always got error in this line of code:
m_lib = LoadLibrary("DiceInvaders.dll");
assert(m_lib);
The error is assertion failure. How should I solve this? Thank you in advance.
First you cannot pass the DLL to the linker like you are, it is not a file type that the linker recognizes and cannot be linked that way. When you create the Diceinvaters.dll file the linker will create an import library with the same filename and the extension .lib. It appears this is already being done. That is the library file you should pass to the linker when building any application that uses it.
Second, the Diceinvaders.dll file must be accessible in the DLL search path. This varies slightly depending on which version of Windows you are using but is generally something like the following
The directory the program was loaded from.
The current working directory.
The System directory.
The Windows directory.
The directories that are listed in the PATH environment variable.
Placing the DLL in your project directory is not going to be enough. Instead you should place it in the same directory as the EXE file(s) that have a dependency on it.
In a Windows environment,
When I tried to link a DLL to my program Explicitly (using LoadLibrary),
First I need to define the function pointers according to each
function signature inside the DLL.
Then get the function addresses using 'GetProcAddress' and assign them to those pointers.
When I tried to link the DLL to my program Implicitly (using header file)
First it need the relevant header file to get function signatures.
Then it needs the relevant Lib file that was generated with the DLL.
My questions are
Why does implicitly linking need a Lib file as well?
What information does it need to retrieve from 'Lib' file that it cannot get from the DLL or Header file?
If there is something for question 2, how is information retrieved when explicitly loading?
I've already gone trough this question. But I cannnot understand any worthy reason.
Please, could someone help to explain this in simple terms. Thank you.
Why Implicitly linking need Lib file too.
The .libs have the import information of the dll, you can check the information using the dumpbin command that is included in Windows/Visual Studio SDK.
This is the link information of recv inside ws2_32.lib for example:
Version : 0
Machine : 14C (x86)
TimeDateStamp: 4907F6ED Wed Oct 29 01:38:53 2008
SizeOfData : 00000014
DLL name : WS2_32.dll
Symbol name : _recv#16
Type : code
Name type : ordinal
Ordinal : 16
You can check there is the ordinal and the name inside ws2_32.dll (check that now it says to import a DLL).
What information it need to retrieve from 'Lib' file that cannot get from DLL or Header file
In the header file, there is no information from where to extract the imports, so them are marked as imports (__imp__name) when compiled, and when it's linked against the .lib, it resolves the name:
If it's inside the .lib it just links against it.
But if there is information on external reference (DLL), it will construct the import inside the import table so it's loaded dinamically.
If there is something for question 2, How those information retrieve when explicit loading.
If for explicit loading you mean the LoadLibrary, you are telling it at runtime and not at link time. So the PE loader will search the DLL inside the PATH and will load it dynamically. Then you have other functions to get the exported functions addresses.
If you don't understand something just ask me, try playing with dumpbin and read about PE if you want to understand this better.
When linking implicitly, the function declaration specifies the name to be used in the program, and the prototype and calling convention. But more information is needed. Specifically:
The fact that the function is implemented externally in a DLL.
The name of that DLL.
The exported name of the function. That is the name used to export the function from the DLL which may not be the same as that used when you import it.
Some language designers chose to provide this information using language extensions. For example Delphi took this route. Implicit linking is specified entirely in code with no .lib files. On the other hand the convention for C and C++ is to use .lib files to specify the missing information.
When I use the following code I get an compilation error
#import <dwmapi.lib>
#include <dwmapi.h>
I get the following error:
fatal error C1083: Cannot open type
library file: 'c:\program
files\microsoft
sdks\windows\v7.0a\lib\dwmapi.lib':
Error loading type library/DLL.
Intellisense says:
2 IntelliSense: cannot open source
file "c:/users/####/documents/visual
studio
2010/Projects/modlauch/modlauch/Debug/dwmapi.tlh":
Bad file
descriptor c:\users\####\documents\visual
studio
2010\projects\modlauch\modlauch\modlauchdlg.cpp 7 1 modlauch
Does anyone know how to solve it? I'm sure that my 'dwmapi' library is fine and there is nothing wrong with it. I'm using MFC with VS2010 , but I don't think that is related to the problem. (Platform - Win32)
If I get rid of "#import" then I get "unresolved external symbol __imp__DwmExtendFrameIntoClientArea#8" error.
This isn't the answer to your problem, but for others who arrive here with that error message - if you accidentally type #import "Header.h" rather than #include "Header.h" when including from a .lib then you will get that error.
dwmapi .lib is a type library? YOu sure its not just a plain old dll. A com lib is either .DLL or .tlb.
I think its a plain old dll. So you dont #import it you need instead
#pragma comment(lib,"dwmapi.lib")
A type library is not a normal object library.
Type libraries are typically found in DLL's, OCX files and TLB files.
The few times I #import'ed a type library it always one of those, never a .LIB file.
Use the REGTLB or REGTLIB command (you may have to look this up in Google) to register a type library in your system. It's similar to REGSVR32, but registers a type library rather than a COM component.
You can also use OLEVIEW to view the contents of a type library.