Bridging unmanaged and managed classes - c++

I have a native C++ class that is exported to a Win32 Dll:
class __declspec(dllexport) Manager { ... }
The Dll is created successfully. Let's call it Unmanaged.dll.
I want to use this class in a .Net application. Therefore, I decided to create managed C++ wrapper classes. So I created a new CLR class library where I set Unmanaged.dll as an input to the linker.
When compiling the managed dll I get the following error:
fatal error LNK1107: Invalid or corrupt file: cannot read at 0x318. (Unmanaged.dll in project ManagedBridge)
Both projects are set to compile to x64. DLL Export Viewer shows the class' constructor and methods. So the Dll seems to be fine.
Is there something I am missing?

You cannot pass a DLL to the linker, it has no idea what to do with it. A DLL is in general not suitable to help a linker determine that the DLL contains the functions you call. Exports from a DLL can be a number of a name. It being a number (an "ordinal") is a problem, the linker will not know how to map the number to the identifier name. And the name does not have to match either, names are commonly simplified with their name decoration removed.
You must instead tell the linker about the DLL's import library. Which has more information, including the ordinal to name mapping and the original decorated name that the compiler used. The import library is a .lib that was created when you linked the DLL. You will find it back in the DLL project's build directory. Add its path to the linker's Additional Dependencies setting.

Related

Getting symbols for explicitly loaded DLL from the application

I am modifying my application so that it can explicitly load a DLL (through the Windows API) and call some functions from the DLL. But I need to be able to call some application's functions from the DLL too. I can only provide header files of the functions to the DLL. But I am getting the LNK2019 'unresolved external symbol' error.
Is my idea even feasible?
So you found a way to do this, however you should also ask yourself whether you should do it.
If your executable depends on the DLL then the DLL should not depend on that executable. This is not just a question about principles but also about avoiding future problems.
The way you could achieve the calls from the DLL to the executable is to define a function-pointer type and a setter in the DLL's headers:
typedef void aCallbackType(void);
void setMyCallback(aCallbackType* Cb);
In setMyCallback the DLL stores that function-pointer to later call it.
Then the executable can define a function and give that to the DLL:
void myCallback(void) { }
void myProgram(void) {
setMyCallback(myCallback);
}
Thank you #AdrianMole for solving my problem! To resolve the external symbols in the DLL you'll need to create an import library of the EXE. In Visual Studio 2017, this can be done by going to the project properties. Go to Linker → Advanced and set the Import Library setting to the path and name you want. (For example: $(TargetDir)\myimportlibrary.implib). Then, go to the the DLL project properties → Linker → Input and add the import library to the Additional Dependencies setting.

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 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.

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.

When building a dll, can the lib be used for linking?

I wanted to create a C++ dll (to be used in a dot net application). Some functionality I needed was already implemented in another C++ dll.
The dll I was referencing was set up like this (including the comment):
extern "C"
{
__declspec(dllexport) BOOL SomeFunctionToBeUsedExternally();
}
// internal functions
BOOL OtherFunctions();
I need to use one of the OtherFunctions in my code.
So, I added the proper include in my own code, added dependencies on the lib created by the dll above, and used the method I needed. As a result, of course, I got another __declspec(dllexport)... function.
It refused to link though, I got an error about the OtherFunction.
I verified everything, looked online - nothing seems to solve my problem.
Then, I added a __declspec(dllexport) in front of the function I needed, and it works.
I don't understand though. I thought, the dllexport marked functions will be exported to the dll, but aren't all functions sent to the lib ?
Why do I have to export functions to the dll, if I am not linking against the dll but against the lib ?
No, the linker does not automatically export all identifiers. The dllexport attribute tells the linker which identifiers are exported. Without this you would be forced to either export every identifier in the DLL or specify which identifiers should not be exported. When the linker creates the DLL it also creates an import library and includes information about which identifiers are exported based on that attribute.
When you want to use a DLL you need link with the appropriate .lib file for good reason. The .lib file tells the linker which identifiers are exported, the name of the DLL they are in and other information. It is also possible to export identifiers from the DLL by ordinal instead of by name. In this case the linker still needs to match the identifier with the appropriate ordinal. This is only possible by having an accompanying library file that contains that information since it is not present in DLL's export table.
No, only exported functions end up in the .lib. As you can tell.
It is not a static link library, it the import library for the DLL. It is a very simple and very small file since it contains no code at all. Just a list of the exported functions. The linker needs it to resolve the external in the client code, it needs to know the name of the DLL and the actual exported function name or ordinal (could be different) so it can add the entry to client's import table. Import libraries having the same filename extension as static libraries was perhaps a bit unfortunate.