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

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.

Related

How to call a function in DLL defined another project

I'd like to call a function in DLL (lets say foo function defined in a X project ). So DLL never knows the exact implementation of this foo function. But later I want to use this DLL in the X project (that contains the foo function).
When I try to compile the DLL, linker gives the "Unresolved external" error. How can I tell the compiler that foo function is defined in another project.
For example;
foo.cpp in DLL project
extern void foo();
void DLLFunction()
{
foo();
}
impl.cpp in X project
void foo()
{
//Do something
}
And if I can compile foo.cpp in the DLL project, I will use this DLL in the X Project.
If I understand the question correctly, you want to have a DLL, which imports a function from the executable it is linked against.
In general it is possible, but tricky, so first thing you should consider is if you really need to do that or if you can change the DLL function to e.g. accept a function pointer (which then does not require to import a symbol from executable into the DLL).
It is still possible to use symbol from executable in the DLL. It is possible to export a symbol (function) from the executable and use in the DLL (normally the same way you export from DLL, e.g. "__declspec(dllexport)" on Windows). However the tricky part is, that by default you need the dependency to link the particular object, i.e. in this case you'd need the DLL to link the executable and the executable to link the DLL, which is a cyclic dependency.
So you need to break the cyclic dependency. There are some possibilities:
Loading the DLL dynamically as a plugin - using dlopen() on Posix and LoadLibrary() under Windows. Then you do not need the DLL to build the executable, and you can link the EXE providing the symbol with the DLL.
The other way around - on Windows, you can dynamically import the exported symbol from the executable into the DLL (GetModuleHandle(), GetProcAddress()).
Allowing the DLL to be build with unresolved symbols. Then you build the DLL with the symbol unresolved, and build the EXE against the DLL. When executed, the executable will load the DLL and will provide the symbol.
To allow building the DLL with unresolved symbols:
In Linux GCC this is the default behaviour (shared objects do not enforce symbols to be resolved), unless you build with "-Wl,--no-undefined".
In Windows MSVC, you can ignore the unresolved symbols when building the DLL by providing the "/FORCE:UNRESOLVED" parameter to the linker. Note that on Windows/MSVC, after you build the EXE .lib file, you then need to rebuild the DLL again against that file to import the symbol.
What you can do is to instead of writing extern, you can load the DLL dynamically
e.g.
auto hd = LoadLibrary("YourDll.DLL");
typedef void(*userfunc)() ;
userfunc p = GetProcAddress(hd, "foo");
p();
Alt. link with the .lib file created when you built the DLL
discalimer: code for cleanup, error checks etc omitted.
If you are using a recent version of the Visual Studio IDE, you can simply reference it - Visual Studio will take care of the rest. To do that, right click on the "References" entry in your Solution Explorer for the project you want to link against your DLL. From there, select the other DLL project in your solution:
This will take care of all the linking required and saves you the trouble of changing your project settings if you rename your projects or change the name of the output-files.
If you don't have the other project in your solution you will have to stick with the regular static linking procedure:
Project Settings -> Linker -> General -> Additional Library Directories
Project Settings -> Linker -> Input -> Additional Dependencies
If you want to dynamically link against the DLL at runtime, you can use the method described by Andreas K.

Use Octave in msvc 2010

I am using Octave within MSVC 2010. First I downloaded Octave latest version at this link. After installing, I tried to run this simple code:
#include <iostream>
#include<octave-3.6.4\octave\oct.h>
#include<octave-3.6.4\octave\config.h>
#include<octave-3.6.4\octave\octave.h>
using namespace std;
int main (void)
{
std::cout << "Hello Octave world!\n";
system("PAUSE");
return 0;
}
Note that I added these links to my project as well:
C:\Software\Octave-3.6.4\include\octave-3.6.4\octave--->Includ. Dir.,
C:\Software\Octave-3.6.4\include--->Includ. Dir.
C:\Software\Octave-3.6.4\lib--->Lib. Dir.
C:\Software\Octave-3.6.4\lib\octave\3.6.4--->Lib Dir.
I also added 1 and 2 to Additional Inc Dir!!
C:\Software\Octave-3.6.4\lib\octave\3.6.4--->Additional Lib. Dir in Linker.
First, I got this error that it cannot find math.h in Program Files while this file was in my Program Files (x86). So, I changed it to: C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\math.h and it solved this error. However, now I get this error:
error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall octave_value::~octave_value(void)" (__imp_??1octave_value##QAE#XZ) referenced in function "public: void * __thiscall octave_value::`vector deleting destructor'(unsigned int)" (??_Eoctave_value##QAEPAXI#Z)
It is not sufficient to add the library path to the project.
You have to add the library name(s) (including .lib) to the "Additional Dependencies" in the Linker/Input tab.
Edit
To verify what library has been searched you can enable the Linker/General/Show Progress option. Then you can see in the Build Output what library has actually be used in symbol search.
Edit
Your example code doesn't show any instance of an array of octave_value instances. So it's a bit surprising that you need to link with any library with the code you've shown. But anyway you want to have these externals resolved.
If there is no other resource (manual, ...) you should detect where the octave_value class is implemented. This can be a static library or a DLL.
You can detect the DLL implementation with a dumpbin /exports on the DLLs. In that case you need the corresponding import libraries. The LIB should have the same base name as the DLL. Verify that you have added that dependency and how the linker searches this library for symbols.
The name of the symbols __imp_??1octave_value##QAE#XZ indicates that it should be in a DLL. But since you have a problem you might want to search LIBs too.
You can detect the LIB implementation with a dumpbin /symbols. In that case you have to add the LIB directly. Again verify it with the Build Output.
The dumpbin output will probably very verbose. You should use either findstr to limit the output or redirect the output to a file and search the symbols with an editor of your choice.
Search for ocatave_value. If you find a different decoration of the constructor and destructor you might have missed to set an option. A preprocessore directory could be used to define how the library is use. E.g. if you find octave_value::octave_value without the __imp_ prefix you have accidentily compiled for a DLL version altough the class is implemented in a static library. In that case, read the manual and ask at the octave mailing list forum or whatever.

Why does Implicit DLL Linking need relevant Lib file but Explicit Linking does not?

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.

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

Creating and linking against a .lib file generated from an old DLL file

I have inherited an old VC++ project that requires an old proprietary .lib file to link against. I have the header file for the lib, but the original developers seem to have lost the .lib file.
I did find a DLL file that I believe a driver from this software package uses that has the same name as the .lib and .h file. I followed these instructions: http://adrianhenke.wordpress.com/2008/12/05/create-lib-file-from-dll/
With that, I was able to generate a .lib file that as far as I know, contains the exact same functions as the .h file I have (the intermediate DEF file shows this). The first project was able to build and link against it successfully, but a second project I have that makes use of the library built by the first project fails to link complaining about unresolved symbols for the functions in the DLL I'm trying to use:
error LNK2019: unresolved external symbol _ncb_receive_wait#12 referenced in function "public: int __thiscall PLC::Write(unsigned short,void *,unsigned short)" (?Write#PLC##QAEHGPAXG#Z)
I'm trying to understand if this is even possible to do? (Grab an old DLL file, generate a lib from it, link against it and use the DLL file?)
I know that this answer is too late for the original question, but hopefully it might help others with a similar problem googling for a solution:
I had a similiar problem linking to an old DLL from Visual C++. I also went down the route of creating a def file and then creating a new lib file from this def file. Then to resolve a linkage error with Visual C++ trying to link to a mangled function name, I manually edited the EXPORTS section of the def file to create a function name alias, along the lines of:
_ncb_receive_wait#12 = ncb_receive_wait
You can try a more automated approach as suggested by MingW to avoid missing a function or other typos.
Otherwise, perhaps the header and binary are incompatible.