I'm trying to create a .lib file to go with an external .dll so we can compile our code against it (VS2010). In this external library functions are declared using __stdcall, they don't specify __declspec(dllimport). Example:
extern "C"
{
int __stdcall exampleFunction(int firstArgument);
}
I've tried the following:
Create .lib from .def
Creating a .def file as follows:
EXPORTS
method_1
method_1#16 #1 ; ordinal from dumpbin
...
Then creating the .lib from this
lib /MACHINE:x86 /def:my_def_file.def OUT:my_library.lib
The code links ok but throws a "Privileged Instruction" exception when first invoking a method from the dll.
Create .lib from .obj
As detailed in this kb another possibility is to create a set of stub functions, compile them into a .obj file and create the .lib from that. I am however unable to even get the example on the kb page to work, e.g.
// my_library.cpp
extern "C" __declspec(dllexport) void _stdcall Function(void) {}
When I run the required commands on this file:
CL /c /Ob0 my_library.cpp
lib /def:my_library.obj /MACHINE:x86
Then opening my_library.obj does show the string "_Function#0", as expected but my_library.lib shows no trace of this. Furthermore I get some funky warning messages when running the lib command:
hasp_api.obj : warning LNK4017: L☺♥ statement not supported for the target platform; gnored
hasp_api.obj : warning LNK4017: ► statement not supported for the target platform; ignored
I'm all for peace and love but I'm kinda stuck and its driving me crazy, any help with either of the methods above would be appreciated!
Related
I try to make simple dll project in Visual Studio 2013 like in http://www.itcsolutions.eu/2009/12/10/how-to-create-a-dll-dynamic-link-library-in-c-as-visual-studio-2008-project/
But when i try to build solution it falls with an error:
error LNK1104: can not open file "D:\prj\dlltest1\Debug\dlltest1.lib" D:\prj\dlltest1\ConsoleApplication1\LINK ConsoleApplication1
But dlltest1 is dll-project. Why there is an .lib file?
Updated: The reason why no libs are generated because you have no symbols exported. I just checked your code.
You should have a *.h file define exported symbols like this.
#ifdef WIN32PROJECT1_EXPORTS
#define WIN32PROJECT1_API __declspec(dllexport)
#else
#define WIN32PROJECT1_API __declspec(dllimport)
#endif WIN32PROJECT1_API int fnWin32Project1(void);
When you created a DLL project, it has some exported symbols other project can use. These symbols' name and offset are stored in *.lib file. *.lib file is created with *.dll files, both of them are put in the output directory.
In the link stage of you ConsoleApplication, the linker try to find the symbols from all your referenced libs (defined in project property) and store these symbols' offset and source dll in output exe file.
You can change the libs settings in Property->Linker
Wikipedia says:
DLL compilation will produce both DLL and LIB files. The LIB file is used to link against a DLL at compile-time; it is not necessary for run-time linking.
The code within your application determines whether compile-time or run-time linking is required:
If you access your DLL functions like
__declspec(dllimport) someFunction(int firstArg, int secondArg)
then your compiler will require both the .dll and the .lib file for linking to the shared library, but during execution, only the .dll will be required.
If you however make use of the DLL functions LoadLibrary, GetProcAddress and FreeLibrary, the .lib will not be required for linking.
I create a set of C++ DLLs and their import libraries in VisualStudio (2013). So far, these were all generated at the same time by linker. My DLLs use symbols from other libraries, which are included as additional dependencies in properties/link edition.
Sometimes, the DLL generation fails because of missing importation libraries, which is fine to me, but in such case there's no generated .lib file either. I would like to generate the import libs (of my DLLs) even if the DLLs cannot be done, in order to allow other projects to rely on the symbols I shall export before I'm able to provide the whole stuff.
I found a workaround through a pre-link event command line, with:
LIB /DEF:(...)\myLib.def /OUT:(...)\myLib.lib $(IntDir)*.obj
This generates exactly what I need, when I do have a .def file.
The problem is, I most often don't have such a .def file but rely on __declspec(dllexport) instructions instead, and in such case I didn't find a way to get a correct result.
I tried:
LIB /OUT:(...)\myLib.lib $(IntDir)*.obj (#1)
This creates a (static ?) lib file, not an import library, not what I need.
LIB /DEF /OUT:(...)\myLib.lib $(IntDir)*.obj (#2)
This fails on error 1104 because of missing (other) import libraries.
What's more puzzling to me is, the command line (#2) fails on libraries that should be here (they are found by the linker, actually). I'm wondering whether I am supposed to provide the complete LINK command line arguments to the LIB command, in which case it would be a no-go.
I'm not much of a specialist of the compilation/link tools, I fear, I'm probably doing pretty wrong stuff...
Does anyone know of a simple way to fulfill my need without using a .def file ? Is there an option in the linker to ask for import library creation from the declared __declspec(dllexport) symbols and generate it even when the DLL cannot link ?
This fails on error 1104 because of missing (other) import libraries.
Edit: oh, I get it. .obj files have /DEFAULTLIB: inside them and lib complains. Use /NODEFAULTLIB
hasunresolved.c:
#pragma comment(lib, "missinglib.lib")
void missingfunc();
__declspec(dllexport)
void dllfunc() {
missingfunc();
}
usedll.c
__declspec(dllimport)
void dllfunc();
int main() {
dllfunc();
return 0;
}
in VS command prompt:
cl -c hasunresolved.c
lib /def /OUT:test.lib hasunresolved.obj
rem this prints: LIB : fatal error LNK1104: cannot open file 'missinglib.lib'
lib /NODEFAULTLIB /def /OUT:test.lib hasunresolved.obj
cl usedll.c test.lib
dumpbin /IMPORTS:test.dll usedll.exe
output:
Dump of file usedll.exe
test.dll
0 dllfunc
I've got a dll from a vendor I want to use in a C++ Visual Studio 2012 project. It comes with a .lib file.
When linking I get:
Error 1 error LNK2019: unresolved external symbol __imp__FT_CreateDeviceInfoList referenced in function "int __cdecl Ftexam(void)" (?Ftexam##YAHXZ) C:\Users\Terry\Documents\Visual Studio 2012\Projects\Win32Project1\Win32Project1\ftexam.obj ftexample
I've read similar posts but I'm not getting anywhere. I think I'm doing everything according to those answers, but I still get a undefined reference error when linking.
I've added the dll.lib file to the /Linker/Addional Dependencies list.
I've made sure the dll.h file is included in my source
I've put the dll.lib file with in my project directory and made sure that if I remove it from there,I get cannot find dll.lib when linking (i.e., it is "in the build")
In my supplied dll.h header file I have this:
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
.
.
#ifdef __cplusplus
extern "C" {
#endif
typedef ULONG FT_STATUS;
.
.
DLL_API FT_STATUS FT_CreateDeviceInfoList(
LPDWORD lpdwNumDevs
);
and my calling code is:
#include dll.h
int Ftexam(){
FT_STATUS ftStatus=0;
DWORD numDevs = 0;
// create the device information list
ftStatus = FT_CreateDeviceInfoList(&numDevs);
}
I realize there is probably some name mangling going on so I looked at the DLL symbols using depends. It lists these exports with the "Undecorate C++ functions" option disabled, (so, these are the unmangled exports):
FT_Open
FT_Close
FT_Read
....
FT_CyclePort
FT_CreateDeviceInfoList< <<<<<this reference!!!!
FT_GetDeviceInfoList
The identified export above obviously does not match __imp__FT_CreateDeviceInfoList
Is there a tool around that can look at the definitions in a .lib file, or some way for visual studio to display that?
UPDATE:
With the use of dumpbin I was able to see the symbol in the .lib was
__imp_FT_CreateDeviceInfoList
instead of
__imp__FT_CreateDeviceInfoList
this I tracked to the .lib for the 64 bit version of the DLL instead of the 32 bit version. (One of the combinations I tried to solve this in the first place).
To simplify the post, I had indicated that the header contained:
DLL_API FT_STATUS FT_CreateDeviceInfoList(LPDWORD lpdwNumDevs);
When in fact, it actually contains:
DLL_API FT_STATUS WINAPI FT_CreateDeviceInfoList(LPDWORD lpdwNumDevs);
because WINAPI was #defined
so changing
#define WINAPI
to
#define WINAPI __stdcall
along with having the correct .lib fixed the issue.
FT_CreateDeviceInfoList() is not declaring any calling convention in the .h file, so it uses whatever the compiler's default calling convention is. Your compiler is defaulting to __cdecl, which is normal behavior for most C++ compilers. Chances are that the compiler that created the DLL is actually using a different default calling convention instead. Try editing the .h file to specify __stdcall, for example, and see if it makes any difference, eg:
DLL_API FT_STATUS __stdcall FT_CreateDeviceInfoList(LPDWORD lpdwNumDevs);
Most DLL vendors use __stdcall for compatibility with the widest selection of compilers, not just C/C++ compilers, though some vendors do use __cdecl or even __fastcall (which is implemented differently by different compiler vendors, so watch out with that one).
Worse case scenario, you can use a disassembler, like IDA or WinDASM, or just use your IDE's own debugger, to look at the actual assembly code for FT_CreateDeviceInfoList() inside the DLL and see how it is managing the call stack when accessing the lpdwNumDevs parameter and returning the FT_STATUS value. That will tell you exactly which calling convention it is actually using.
UPDATE: doing some online searches, I see many examples of .NET code that call FT_CreateDeviceInfoList() with the __stdcall calling convention applied to its declaration, so that is a good place to start. If that works, then you should contact the DLL vendor and ask them to fix their .h file accordingly.
Open a Visual Studio command prompt. Fire the following command to list the symbols in the lib file:
dumpbin /all dll.lib
Redirect the above to a text file, as the output scrolls off quickly
What you're doing should work as far as I can see. But you can always just forget about the .lib file and use the DLL directly, loading it with LoadLibrary and getting the addresses of the functions you want to use with GetProcAddress.
A friend of mine gets a bunch of error when creating a DLL. Visual Studio complains about unresolved external symbols. I am mainly an Unix user so I might be mistaken there. On Unix, when you create a static library (an archive), it does not do much more than concatenating the different object files into an archive file. I would expect dynamic objects to be created the same way, but apparently, an extra link stage takes place.
First question: Why is there a link stage for the dll?
In this case, the DLL indeeds contains undefined symbols because we expect the DLL to find those symbols within the EXE file. This is quite opposite the typical DLL behaviour, where an EXE uses the symbols defined in the DLL. To make it clear, I expect those symbols to be found right when the DLL is loaded in memory.
Second question: How can I make a DLL use symbols defined in the EXE file?
EDIT:
I reformulated the question, as I think I did not state the problem clearly enough.
You described the origin of your problem as: "I want the DLL to import some symbols from the exe file" in the comment to the answer of Luchian Grigore. You wrote additionally in the text of your question that you want "the DLL to find those symbols within the EXE file. we expect the DLL to find those symbols within the EXE file."
Mostly it's design question whether to export functions or data from the exe or not. Typically one creates export only from DLL. If EXE need to provide some information to DLL it provide the information by parameters. For example you an call in EXE some function MyFunc implemented and exported in the DLL. As additional parameter of MyFunc you get context pointer which can get DLL directly or indirectly all information for EXE which needed.
In some seldom situations you do can export data or functions from EXE. For example you an use DumpBin.exe utility (just start "Visual Studio Command Prompt (2010)" to use it) to verify that Outlook.exe exports
DumpBin.exe /exports "C:\Program Files\Microsoft Office\Office14\OUTLOOK.EXE"
File Type: EXECUTABLE IMAGE
Section contains the following exports for outlook.exe
00000000 characteristics
4E79B6C8 time date stamp Wed Sep 21 12:04:56 2011
0.00 version
1 ordinal base
66 number of functions
66 number of names
ordinal hint RVA name
1 0 00B58A88 CleanupAddressComponents
2 1 00B58A88 CleanupNameComponents
3 2 00228DC4 DllCanUnloadNow
4 3 004848F8 DllGetClassObject
...
65 40 0038EF30 UpdateContactTracker
66 41 00902788 dwIsLoggingEnabled
I can explain how you can implement the scenario without long discussion when and whether you really should do this.
First of all the LIB file contains OBJ files which has another format as Program Executable (PE). During compilation different common section will be placed in OBJ file. It's very important, that program executable (EXE or DLL) contains not only from the code, but it has many additional information in the header part of the PE. The most important are
Export Directory
Import Directory
Import Address Table Directory
Base Relocation Directory
Resource Directory
You can use DumpBin.exe utility (just start "Visual Studio Command Prompt (2010)" to easy use it). To see information about the headers you can use DumpBin.exe /headers my.exe. To see contain of the Export Directory you can use DumpBin.exe /exports my.exe and so on.
If you compile DLL which exports some functions or data the LIB file will be additionally created. It's so named import library. If you use the LIB in your EXE project which uses some functions or data from the DLL the linker will resolve the external references and places in import directory of EXE information about the functions which should be resolved at the load time.
So the import library contains only the templates for filling Import Directory and Import Address Table Directory in EXE.
In general one can in the same way export some data of functions from EXE, create LIB, uses the LIB in the DLL project and in the way implement importing some information in DLL from EXE.
I made the demo project which demonstrate the way. Please, read carefully the compilation instructions at the end of my answer if you want delete all LIBs from the Project and create all yourself. The code of ExportFromExe.c (the EXE):
//#define CREATE_IMPORT_LIBRARY_ONLY
#include <Windows.h>
EXTERN_C __declspec(dllexport) int someData = 0;
EXTERN_C __declspec(dllexport) int __stdcall myFunc (int x);
EXTERN_C __declspec(dllexport) int __stdcall MyFunc();
int __stdcall myFunc (int x)
{
return x + 10;
}
#ifndef _DEBUG
int mainCRTStartup()
#else
int main()
#endif
{
someData = 5;
#ifndef CREATE_IMPORT_LIBRARY_ONLY
return MyFunc();
#endif
}
The code of MyDll.c (the DLL):
#include <Windows.h>
EXTERN_C __declspec(dllexport) int myData = 3;
EXTERN_C __declspec(dllimport) int someData;
EXTERN_C __declspec(dllimport) int __stdcall myFunc (int x);
#ifndef _DEBUG
EXTERN_C BOOL WINAPI _DllMainCRTStartup (HINSTANCE hinstDLL, DWORD fdwReason,
LPVOID lpvReserved)
#else
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
#endif
{
if (fdwReason == DLL_PROCESS_ATTACH)
DisableThreadLibraryCalls(hinstDLL);
return TRUE;
UNREFERENCED_PARAMETER (lpvReserved);
}
EXTERN_C __declspec(dllexport) int WINAPI MyFunc()
{
return someData + myFunc(myData);
}
To be able to create the project successfully at the first time we have to solve the problem: "who was first: the chicken or the egg?" because the EXE project depend from MyDll.lib and the DLL project depends from ExportFromExe.lib. For the first compilation of EXE we can temoprary remove $(OutDir)MyDll.lib from the linker setting of EXE project and define CREATE_IMPORT_LIBRARY_ONLY. As the result we'll create ExportFromExe.exe and ExportFromExe.lib. In more large projects one can use Undefined Symbol Only (/FORCE:UNRESOLVED) option of linker instead. Then we can build MyDll project which creates MyDll.dll and MyDll.lib. Now you can remove CREATE_IMPORT_LIBRARY_ONLY from the EXE and include $(OutDir)MyDll.lib as the linker setting ("Additional Depandencies" in "Input" part of settings). The next build of EXE project produce the final solution.
I used some small tricks to remove C-Runtime and reduce the size of EXE and DLL to 2,5 or 3 KB. So you can use /all switch of DumpBin.exe to examine full information from EXE and DLL inclusive RAW binary data.
Because the EXE return results as ERRORLEVEL you can test the application in the commend prompt:
echo %ERRORLEVEL%
0
ExportFromExe.exe
echo %ERRORLEVEL%
18
First question: Why is there a link stage for the dll ?
Because that's the way it is. There's a linking stage everytime you want to create a binary. The symbols need to be resolved somehow, right?
Second question: How can I do that ?
You add the lib file that is generated alongside the dll to the Additional Dependencies from your project - Properties -> Configuration Properties -> Linker -> Input
Note:
In case you don't already do this, in order to be exported to the lib, symbols must be declared with _declspec(dllexport). When you include the headers, you tell the compiler that those symbols are to be imported with _declspec(dllimport).
I am trying to create an application in visual studio that will be able to access a .dll file that already exists. I need the application to call up routines. I also have a header file that already exists.
I have been researching on the internet and have found that I need to create a .lib file. Looking at similar questions on here I found a link: http://support.microsoft.com/kb/131313
I cannot however follow the directions.
The information in the link says to make a DEF file ( I read elsewhere that this needs to be compiled as a DLL with the same name, but not sure what that name is, the same name as the .dll file?). But I do not understand the first direction, to 'Use DUMPBIN /EXPORTS'. I then need to 'stub out' functions, and then something to do with .OBJ files (I do not know what these files are).
Are there any step-by-step directions, similar to the link above, that are easy to follow?
You're going to need Microsoft Visual C++ 2010 Express (or any other source of MSVC command line tools), and your DLL.
Steps:
dumpbin /EXPORTS yourfile.dll > yourfile.exports
Paste the names of the needed functions from yourfile.exports into a new yourfile.def file. Add a line with the word EXPORTS at the top of this file.
Run the following commands from VC\bin directory (the one where lib.exe and other compile tools reside).
vcvars32.bat
lib /def:yourfile.def /out:yourfile.lib
or for x64 builds
lib /def:yourfile.def /machine:x64 /out:yourfile64.lib
You should get two files generated: yourfile.lib and yourfile.exp
You can use Digital Mars's IMPLIB tool. It can create a lib file using only the dll, without any need for a .def file.
The download link is http://ftp.digitalmars.com/bup.zip.
The command line is:
implib.exe /s mydll.lib mydll.dll
There is a much simpler way to create a .def file. Search the web for the gendef utility (you may already have it if you have Mingw-64). Once you have it, just go to a command line and type,
gendef myfile.dll
And it will create a myfile.def. After that, just use lib.exe to create the myfile.lib file as explained by John.
Here is a solution using Cygwin:
install gendef and mingw64-x86_64-binutils Cygwin packages
run in Cygwin console:
gendef.exe awesome.dll
x86_64-w64-mingw32-dlltool.exe -d awesome.def -l awesome.lib
you get awesome.lib in the same dir.
VS 2019 linker linked just fine using this file.
I might have the answer. I did this when I was creating a .exe console application that needed a .dll file. I ran into the problem as well. When I tried the IMPLIB application, it couldn't find any export files. You need to add an #ifdef FILENAME_EXPORTS (replace FILENAME with your .dll file name) and create an _API. Here is the code for the #ifdef export api commands:
#ifdef FILENAME_EXPORTS
#define FILENAME_API __declspec(dllexport)
#else
#define FILENAME_API __declspec(dllimport)
#endif
Now that you have the Export API defined, you need to apply it to all the functions in your header file in the .dll project. For example:
void FILENAME_API function();
Declare your export functions normally, but include the API between the declarer type and the function name.
For defining the function in the .cpp file in the .dll project, you don't need the API in the declaration.
Here is an example of filename.h and filename.cpp with all the code.
// Code for filename.h
#pragma once
// Define your Export API
#ifdef FILENAME_EXPORTS
#define FILENAME_API __declspec(dllexport)
#else
#define FILENAME_API __declspec(dllimport)
#endif
// Declare your functions with your API
void FILENAME_API function1();
void FILENAME_API function2();
void FILENAME_API function3();
-------------------------------------------------------------------------------------------
// Code for filename.cpp
#include <iostream>
#include "pch.h"
#include "filename.h"
using namespace std;
void function1()
{
cout << "Hello Function1!";
}
void function2()
{
cout << "Hello Function2!";
}
void function3()
{
cout << "Hello Function3!";
}
Now when you compile the project, you should see the .dll, .lib, and .exp files in the folder where the compiled files are saved to. Now you can link the .exe file with the .lib file. You're Welcome!
First type
#define YOURPROJECT_API _declspec(dllexport)
void yourf()
cpp
#include "pch.h"
#include "YOURPROJECT.H"
void yourf() {}
then include them
linker->input->def file then inhert from parent or project default
compile