Using a DLL project in a Win32 Project from same solution - c++

I have a solution which contains a DLL project and a Win32 EXE project.
I want the EXE project to reference an "Init" function in the DLL.
In the EXE.cpp file I have
extern DWORD __declspec(dllexport) Init(int num);
and I reference it like so
Init(0);
in the EXE project properties, I have gone to the linker's "Additonal Dependencies" and added "mydll.lib", and in the General tab, I have added the directory to where "Additional Library Directories" will point to my DLL's generated mydll.lib file
I do not get any compiler complaints about being able to find the file mydll.lib, but I do get
error LNK2019: unresolved external symbol "unsigned long __cdecl Init(int)" (?Init##YAKI#Z) references in function _wmain
What am I doing wrong to be able to link the DLL that's being built in the same project as my EXE? When I do a dumpbin /exports mydll.lib the only thing I notice is that my Init function lists as _Init

From the comments:
Your DLL was written in C but you are trying to use it from a C++ program. The C++ compiler does not know that it is a C function, it assumes it is a C++ function. Wrap the #include for the .h file with extern "C" {}. – Hans Passant Jul 24 at 22:54
Wow..thanks for the help! Make that an answer and I will accept. I totally forgot to strip the .cpp down to .c for the new project when I added it, and didn't realize that until you said something. This has to do with the way the compiler does name mangling for CPP, am i right? – Derek Jul 24 at 22:56

Related

DLL needs symbols (a class) from the app it will link to

I cannot get a DLL to link, that needs a class exported from the app this DLL will be used with. Visual Studio 2008, Windows 7.
I had a small sample DLL compiling (the default MSFT DLL project actually), and the app can use LoadLibrary() and GetProcAddress() on it correctly. I'm experienced with dllimport/dllexport. Using dumpbin /exports was critical to discover the mangled names to use with GetProcAddress() (MSFT's default empty DLL includes a sample function without extern "C") but this is a solved problem.
The next step was to have the app export a class that the DLL will need to subclass. I do the dllimport/dllexport #define's in the reverse sense from usual: a special symbol when the app is compiled tags the class with dllexport and non-app code (such as the DLL) using that header, without the special symbol, gets a dllimport spec. dumpbin /exports on the .exe file shows exactly this class's (mangled) symbols being exported, and no others, as expected.
The next step was to have the DLL include the header and create an object of the exported object's type (as a baby-step towards actually subclassing it). Compiles fine, but linker shows error:
DynTest.obj : error LNK2019: unresolved external symbol "public: __thiscall Test::Test(class Toast*,double)" (??0Test##QAE#PAVToast##N#Z) referenced in function "public: __thiscall CDynTest::CDynTest(void)" (??0CDynTest##QAE#XZ)
OK, that didn't surprise me, as I know on WIN32 I need to supply DLL's at link time to make a DLL, unlike my usual Unix. Since Windows seems to treat DLLs and executables a bit similarly, I tried adding the .exe at Properties->Configuration Properties->Linker->Input->Additional Dependencies. That gets an error that looks like LINK.EXE didn't auto-detect that it was being given an .exe:
T:\mypath\MyBinary.exe : fatal error LNK1107: invalid or corrupt file: cannot read at 0x348
I then tried adding instead the object file that defines this class... That seems to be understood by the linker, and is probably successfully satisfying the DLL's need to link, but now shows a myriad of other symbols this file depends upon.
So I've considered refactoring the app such that most of it is in a DLL or LIB, just so I can supply that as an "Additional Dependencies" to the DLL I'm actually worried about. But this seems to be draconian. Is that my only option?
Invoking dumpbin /exports gives you a list of mangled names of exe exports. You need to create a module definition file (.def) containing these names:
EXPORTS
#d3d_some_fancy_mangedled_method_1
#d3d_some_fancy_mangedled_method_2
...
Notice that it is basically dumpbin output with first columns removed.
Then you use lib tool to generate export library from module definition file:
LIB /DEF:prog.def /NAME:prog.exe /MACHINE:x86
Finally you link generated export library prog.lib into your application. /MACHINE option should match to your executable. Notice that you don't need to link or anyhow use program executable to link it, only export library is used.

How do I link a DLL to my project? error LNK2019: unresolved external symbol

I have a file foo.h that has various declarations for functions. All of these functions are implemented in a file foo.dll. However, when I include the .h file and try to use any of the functions, I get the error:
bar.obj : error LNK2019: unresolved external symbol SomeFunction
so obviously the function implementations aren't being found.
What do I have to do to help the compiler find the definitions in the DLL and associate them with the .h file?
I've seen some stuff about __declspec(dllexport) and __declspec(dllimport) but I still can't figure out how to use them.
You should have received at least three files from the DLL owner. The DLL which you'll need at runtime, the .h file with the declarations of the exported functions, you already have that. And a .lib file, the import library for the DLL. Which the linker requires so it knows how to add the functions to the program's import table.
You are missing the step where you told the linker that it needs to link the .lib file. It needs to be added to the linker's Input + Additional Dependencies setting of your project. Or most easily done by writing the linker instruction in your source code:
#include "foo.h"
#pragma comment(lib, "foo.lib")
Which works for MSVC, not otherwise portable but linking never is. Copy the .lib file to your project directory or specify the full path.
I just had a similar problem. The solution turned out to be that the DLL was 64 bit, and the simple app using it was 32. I had forgotten to change it to x64 in the Configuration Manager.
You need to specify in front of function definitions __declspec(dllexport) keyword at the time of building the dll
You need to import or load the .dll file into process memory.
You need to acquire the address of function you want to use from that dll.
Some useful links to get started:: MSDN Documentation, SO, Random

Magick++ in VS2010 - unresolved external symbol

I'm trying to use ImageMagick Magick++ for a C++ Project in VS2010.
I installed the Library from here: klick
Then in my Project, I added c:/program files/ImageMagick-6.6.6-Q16/include to the include folders. Then I tried to use Magick++ with this code:
#include <Magick++.h>
void main(int argc, char ** argv){
InitializeMagick(*argv);
}
But this does not work!
VS2010 returns the following errors:
error LNK2001: unresolved external symbol "__declspec(dllimport) void __cdecl Magick::InitializeMagick(char const *)" (__imp_?InitializeMagick#Magick##YAXPBD#Z)
error LNK1120: 1 unresolved externals
What am I doing wrong?
Thanks very much for your help!
UPDATE:
Set Linker -> Input -> Additionnal Dependencies to:
kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;CORE_RL_Magick++_.lib
And Linker -> General -> Additionnal Library Directories to:
C:\Program Files\ImageMagick-6.6.6-Q16\lib
It still results in the same error...
UPDATE 2
Opening the .lib files in C:\Program Files\ImageMagick-6.6.6-Q16\lib results in this error:
UPDATE 3
CORE_RL_Magick++_.lib does contain ?InitializeMagick#Magick##YAXPEBD#Z, but not ?InitializeMagick#Magick##YAXPBD#Z. Does this mean the .lib file is corrupted?
UPDATE 4
I solved my problem by manually compliling the .lib files.
Thanks to all!
CORE_RL_Magick++_.lib does contain ?InitializeMagick#Magick##YAXPEBD#Z, but not ?InitializeMagick#Magick##YAXPBD#Z
Using the undname.exe utility, these names undecorate to:
void __cdecl Magick::InitializeMagick(char const *)
void __cdecl Magick::InitializeMagick(char const * __ptr64)
Note the __ptr64 declarator you got on the argument. You've got some kind of compile setting that turns that char* into a 64-bit pointer. Like compiling this code targeting a 64-bit operating system. But linking the 32-bit .lib. This normally generates a linker error about the bit-ness of the .lib being wrong, not so sure why you don't see this. Maybe a mingw artifact, not sure how it works.
You should also indicate to Visual Studio the .lib to be used for linking
in Linker -> Input -> Additionnal Dependencies
EDIT: and put the path of the magick library
in Linker -> General -> Additionnal Library Directories
EDIT2: if it still doesnt work, then you are calling a fonction with a wrong exported signature.
Launch the msdev tool Dependency Walker. And check if the magick.lib really exports the function whose name is ?InitializeMagick#Magick##YAXPBD#Z
I am wrong it's not a microsoft tool: Dependency Walker
I was wrong Dependency Walker doesnt open .lib, only Dlls and Exes.
However since you have found ?InitializeMagick#Magick##YAXPBD#Z in the content of the .lib file, it means that it is reaaly exported this way.
EDIT3: Are you SURE the name and the folder of the additionnal library is correct. I really cannot think of another reason for Visual C++ being unable to link with your library. If your .lib DO contains the string ?InitializeMagick#Magick##YAXPBD#Z I really think it should link.
EDIT4: could you paste from the file <Magick++.h> the prototype definition of InitializeMagick ?
there is something that makes it be compiled differently between visual c++ and your library supplier. ?InitializeMagick#Magick##YAXPEBD#Z and ?InitializeMagick#Magick##YAXPEBD#Z are two DIFFERENT signatures. When including <Magick++.h> Visual C++ understands its differently. (that's why I need to see the prototype of the function)
You should also indicate to Visual Studio the .lib to be used for linking
in Linker -> Input -> Additionnal Dependencies
Thank you!
The additional dependecies line contains now the following text (look at the end):
kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;C:\Program Files\ImageMagick-6.6.6-Q16\lib\CORE_RL_Magick++_.lib
It still does not work. Is it the wrong .lib file?
what is this .lib file for?
Shouldn't source code just work? There isn't any DLL...
The documentation says: "Windows users may get started by manually editing a project file for one of the Magick++ demo programs." Did you try that?

C++ #include external function issue

I'm a real beginner and I'm programming in C++ using Visual Studio.
I've a simple cpp code that recalls some functions written in a .c and .h file. I included that file by means of #include directive and the IDE "sees" the function.
When I compile, I get this
Error 7 error LNK2019: unresolved external symbol _IMUsendAccelToFIFO referenced in function _main D:\Cprojects\Pencil\Pencil\Pencil.obj Pencil
What am I missing here?
Thank you all!
It is a linker error, not a compiler error. The compiler is happy, it saw the declaration of function in the .h file. The linker isn't, it cannot find the definition of the function.
Add the .c file to your project.
If you get an error in Visual Studio you can actually google for the error code and you will get pretty extensive information for that. In this case, googling LNK2019 gives this MSDN page as first hit, which also provides some examples on how you get the error.
Your vendor should have provided some .lib files for you (usually found in a folder named lib?). Make sure that these are added in the project via:
Project > Properties > Configuration Properties > Linker > Input > Additional Dependencies
You could also see if there is any "get started" information for you from your vendor, which explains which dependencies you have to include in your project.
If you feel unsure of what a compiler and what a linker does, pick up a book that explains it, or browse some free alternatives.
Are you using ghettopilot? that's the only reference I can find on the web to the function you're missing. If you are, then you need to include the .lib file for that library in your link options.
Visual Studio will compile .c files as C and .cpp files as C++ by default, and this can cause trouble because if you want to call functions defined in a .c file from a .cpp file, then you must wrap the header in extern "C" { }, as the compiler will expect all functions not declared extern "C" to be from C++. This is because of an implementation detail called name mangling. Alternatively, you could force all files to be compiled as C or as C++ in the project settings.
Solved! Thank you very much!
The libraries I was using needed to be built. I tried but I couldn't build them as I used to get "heap space" error!
I installed Visual Studio 2005 (with which the code was produced by the vendor) and it worked at first attempt! There are probably some back-compatibility issues..

How to import external dll library to Borland C++ 6?

I build an application in Borland C++ 6 and I'd like to import external, non Borland library (FFTW, to be exact, http://www.fftw.org).
I have downloaded the fftw dll file, used the implib.exe program to build a lib file known to Borland, included fftw.h in source and copied fftw.h to Borland/include, fftw.lib to Borland/lib and .h, .dll and .lib files to my project folder.
Unfortunately I get several linker errors, which claims:
Unresolved external '{name of the FFTW function}' referenced from {name of the source file}
What do I do wrong?
I'm just telling from a similar story how I managed to get it to work...
There was a DLL that worked (was being sucessfully imported) with Delphi 7, VB.NET and Java. I wanted to make a program with Borland C++ Builder 6 with it. I had the function prototypes and the exact declarations that made the import on those languages. Reasonable?
I thought it would be easy, but I stucked on many dead ends without sucess, with step by step "blind" guides that didn't worked for me. And the IDE or command outputs not helping either.
After a few days I tried (from question 4599357, although the DLL isn't in Visual C++):
using "implib" without "-a" and
having the prototypes declared like this:
extern "C" __declspec(dllimport) __stdcall int someDll_someFunction(someTypes someArgs, ...);
Note that the normal function prototype is at the end. If you have the "normal" prototypes, just add "extern "C" __declspec(dllimport) __stdcall" before them to your source code or header file. :) And I only have functions that return "int", this is why I put "int" there.
I think you're only missing one step... add the .lib file that implib created to your project.
Are you sure that Borland is doing proper name-mangling of the external functions, and that the header has been surrounded with extern "c" {}? And are you sure that Borland is indeed trying to link with the .lib file? Make sure the compiler has the verbose option set.
If that doesn't work, why don't you build FFTW from source instead of using a DLL?