Link imports by name (C++/Visual Studio) - c++

I have a few NT imports I want to use in my program, problem is I am unable to use them without going though the lengthly process of downloading and setting up the WDK to use just two functions. I would also prefer not to use GetModuleHandle and GetProcAddress.
I know in VB6 you can manually define imported functions from dlls like this:
Private Declare Function NtFunction Lib "ntdll.dll" (function arguments) As type
Is there something similar I can do with C++ in Visual Studio without having all the headers/libs?

You say you don't want to use GetProcAddress, but that's exactly what VB6 Declare Function (and .NET p/invoke) does.
You do need a complete prototype, often you can recreate enough of the header file from documentation.
The import library is a little more difficult, but there are tools to create import libraries from the .DLL.
If you create a .DEF file, you can use the LIB.EXE tool that comes with Visual C++ (and also available as a free download as part of the Windows SDK), see Building an Import Library
Here is some more information.
mingw comes with a tool for mostly automating creation of the .DEF file: http://www.mingw.org/wiki/CreateImportLibraries (the import library it creates is only usable with gcc, but the .DEF file is useful for making a VC++ import library as described above).
Here's a another tool that might help: http://www.codeproject.com/KB/tips/ImpDef.aspx

Related

Pros and Cons of Using .def Files

I don't understand this paragraph :
Exporting functions in a .def file gives you control over the export ordinals. When you add an exported function to your DLL, you can assign it a higher ordinal value than any other exported function. When you do this, applications that use implicit linking do not have to relink with the import library that contains the new function. This is very convenient if you are designing a DLL for use by many applications because you can add new functionality and also ensure that it continues to work correctly with the applications that already rely on it. For example, the MFC DLLs are built by using .def files.
Why application doesn't have to relink with the import library in case of the usage of a .def file instead of __declspec(dllexport) in the case of a function adding into the dll ?
cf https://learn.microsoft.com/en-us/cpp/build/determining-which-exporting-method-to-use
That is because of some specifics of MSFT implementation of shared objects (or DLLs). In Microsoft world, in order to import function into your process, you need not only the shared code itself (.dll), but you also need the special 'import' library - the .lib file. This file is statically linked into your application (as it is a static library). This library provides 'glue' between function names and function ordinals.
Normally, every time you release a new version of DLL, all applications which use it will have to be relinked with the new, accompanying version of static import library (.lib) to be able to use this new DLL library. This is due to the fact that function ordinals are generally no longer valid after you have created the new library. However, if you are using .def file, you can assign ordinals manually, and ensure the ordinals remain the same for previously available functions - and thus .lib file will still be valid.
Ok, if you have a .def file you can use it to create an import library.
I.e. mydll.lib for MS VC++ or mylib-dll.a for GCC
Compilers and linkers prefer their own binary format import libraries, usually not compatible with each-other. This is especially does mater when you'r DLL is written on C/C++ but your program is written on something else like Ada/FORTRAN/Object Pascal etc or vise versa. So .def files can be used to create a compatible import library.
Paragraph telling you a way to hide some functions from import library, with manual editing .DEF file and instruct linker to hide some functions.

Construction of a .dll file and the intermediate .lib

Below is an excerpt from link1.
Microsoft introduced __export in the 16-bit compiler version of Visual
C++ to allow the compiler to generate the export names automatically
and place them in a .lib file. This .lib file can then be used just
like a static .lib to link with a DLL. In newer compiler versions, you
can export data, functions, classes, or class member functions from a
DLL using the __declspec(dllexport) keyword. __declspec(dllexport)
adds the export directive to the object file so you do not need to use
a .def file.
I understand the above paragraph to an extent but not very well.
Below is an excerpt from link2.
When building the DLL, the linker uses the .def file to create an
export (.exp) file and an import library (.lib) file. The linker then
uses the export file to build the DLL file. Executables that
implicitly link to the DLL link to the import library when they are
built.
Now, this makes me confused and made me ask the below questions:
Could anybody, in simple words, tell me what the term exporting
really means? I believe this is making an object accessible from one
piece of the code to other - but hey !!
When building projects with old libraries, I see .def file in majority
of them. But the latest compilers automatically exports objects. Would
the presence of the .def file cause any conflict when converting a older
version visual studio project to the newer one?
What is the use of the .lib(the so called import file) after the generation
of the .dll. Can it be safely deleted?
ARRGGGH !! What is the difference between a static library(.lib) and import library(.lib)? Blunder, huh? But still !!
Is the windows specific phenomenon? I believe it is not. What is the Linux counterpart of the so called import file?
Please feel free to rephrase the question if it is not already lucid.
tell me what the term exporting really means?
It simply means telling the linker that it needs to put an entry into the DLL's export table. The operating system loader uses it later to glue code in different modules together at runtime.
I see .def file in majority of them
Could be very old projects. Or it was just never started as a project that was meant to create a separate module. Like a static library so the source code doesn't have the __declspec attributes. Cross-platform libraries are pretty likely to fit that bill. The C and C++ language specifications still don't have a way to create modules in a standardized way. Everybody does it, nobody does it the same way. Massive time drain.
What is the use of the .lib(the so called import file)
It is necessary in the project that uses the DLL. The linker needs to know that the identifier lives in another building and can't be resolved at link time. It puts an entry in another table that the operating system loader uses, the import table. It is a very simple file, it just list the names of the exported identifiers. Theoretically the DLL itself could be used by the linker to figure this out. Practically that doesn't work because the exported name doesn't have to match the actual name.
What is the difference between a static library(.lib) and import library(.lib)
A static library contains code that is linked into the project that uses the library. An import library does not contain code, just a hint that the code is available elsewhere.
Is the windows specific phenomenon?
Roughly, yes. The Unixes have the same concept but implement it very differently.

Renaming dll (TBB + OpenCV)

I have built OpenCV (dynamic libs) with TBB support using CMake and VS2010. However, for the integration of my plugin (that uses opencv calls) in an external host application, i have to rename the tbb.dll, since the host application already includes a tbb.dll but using a different version.
I read that DUMPBIN and LIB commands can be used to obtain the list of export symbols for the dll to create an import library. However, according to http://support.microsoft.com/kb/131313/en-us this is only possible for export functions using a C interface, but the Dependency Walker shows that both C and C++ interfaces are used.
So, is there a "simple" solution to rename the tbb.dll afterwards (i.e. after OpenCV was compiled)? Or do you have any hints how this can be accomplished?
Thanks in advance!
It's not a nice solution, but it is possible to patch dll-s! Eg. replace any reference to tbb.dll in a dll to tbc.dll. You can just use a hex editor for this, or write a script.

Dll dependency version conflict

I am using C++ with Visual Studio 2008 Express.
We are supplying a binary-only Windows library to a client, which itself uses a number of other libraries. Therefore we shipped both our dll file, along with the dll files that we use. Now the issue is that our client uses some of the libraries that we also use, but in another version. Therefore he can not use our library, since the libraries we both depend on are incompatible.
Technically I think it should be possible that both dependency versions are loaded into the process space. However, I am unsure how to do this, as both their application, as well as our dll look for the same dependency dll file name. Can anyone tell me what the best/cleanest way to deal with this problem is?
Thanks!
Generally speaking, it won't work. This is due to the fact that the third party DLL versions might interfere with each other when loaded into memory. One example could be if there is an exclusive resource like e.g. a file in a specific directory. Or a specific device. The problem is, nobody knows probably not even the manufacturer of the 3rd party DLLs - so extensive testing is necessary.
But maybe you're lucky and it works anyway. My recipe:
Put your DLL "DTAG.DLL" and all needed DLLs in a subdirectory of the applications directory with a fixed name e.g. "DTAG_LIB".
Write a import library by hand (there are other possibilities using DELAYLOAD). In that library load your DLL with LoadLibraryEx. Provide an absolute path ending with "DTAG_LIB\DTAG.DLL" and the flag LOAD_WITH_ALTERED_SEARCH_PATH. Windows will then load your DTAG.DLL from this directory and all needed DLLs from that directory also. Don't set the PATH to "DTAG_LIB"!
Your customer has to link against your manual import lib.
You could solve this kind of problem using a (new) additional DLL you would deliver and that would take care of handling the versions conflict (at runtime) - being a kind of proxy between your app and its dependencies.
An alternative would be to use the Windows Forwarded Libraries mechanism.
Forwarders are a handy way to accommodate functionality moving from one DLL to another
You can use several ways to declare forwarders, such as a module definition (.def) file and a #pragma:
#pragma comment(linker, "/export:function=otherdll.function")

How to use a DLL without the need of its .h and .lib files in a VC++ 6.0 Project?

I don't know how to do the following:
I'm using MS Visual C++ 6.0
I have a Win32 DLL project which is compilable.
I have another project, this time a Win32 Console project which uses
the DLL by including it's header file and linking the .lib file of
the DLL.
Now I want to have another project, similar to the second BUT without using the header file and the lib file.
Is that possible? Everywhere I read you need either dll+lib+h or dll+h. If thought if you know the interfaces, a DLL file is sufficient?
Btw, by "using a DLL" I mean, using the Classes and Functions defined in the DLL.
It is possible if you just have plain "extern C" functions. If this is the case the approach could be loading the dll with LoadLibrary, and then import each function with GetProcAddress, of course you need to know the function signature to create a properly declared function pointer. Using classes per contrary is almost impossible.
If your DLL contains classes, there are good chances that it is a COM component.
If this is the case, the #import directive (that you use like #include) builds some temporary include files containing the interface details. You should use COM to access your objects.
Otherwise, if you have a 'plain' DLL with C++ classes, you could access the exported symbols using linker: instruct it to dump the map (see here), to know the mangled names. But I don't think that's possible to build manually the interface...