Hi all,
I am working on Explicit Linking of a DLL to an executable. Theoretically, I really understand what it means. But, when it comes to application, I have some troubles.
1) I try to export a class using C Language approach. (I would ask for other approaches later).
My dll project as follows:
dllmain.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
|
Final2DLL.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
//Final2DLL.h
#ifdef FINAL2DLL_EXPORTS
#define FINAL2DLL_API __declspec(dllexport)
#else
#define FINAL2DLL_API __declspec(dllimport)
#endif
#ifdef __cplusplus
struct IFinal2DLL
{
virtual int Foo(int n) = 0;
virtual void Release() = 0;
};
// Handle type. In C++ language the iterface type is used.
typedef IFinal2DLL* FINAL2DLLHANDLE;
#else // C
// Handle type. In C language there are no classes, so empty struct is used
// in order to ensure type safety.
typedef struct IFinal2DLL {} * FINAL2DLLHANDLE;
#endif // __cplusplus
////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
# define EXTERN_C extern "C"
#else
# define EXTERN_C
#endif // __cplusplus
// Factory function that creates instances of the Final2DLL object.
EXTERN_C FINAL2DLL_API FINAL2DLLHANDLE GetFinal(VOID);
////////////////////////////////////////////////////////////////////////////////
// Classic C interface.
// These functions can be used with any compiler that knows how to call
// an exported C routine.
EXTERN_C FINAL2DLL_API INT FinalFoo(FINAL2DLLHANDLE handle, INT n);
EXTERN_C FINAL2DLL_API VOID FinalRelease(FINAL2DLLHANDLE handle);
|
Final2DLL.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
// Final2DLL.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#define FINAL2DLL_EXPORTS
#include "Final2DLL.h"
#include <iostream>
////////////////////////////////////////////////////////////////////////////////
// Implementation of the IFinal2DLL interface.
class IFinal2DLLImpl : public IFinal2DLL
{
public:
int Foo(int n);
void Release();
};
int IFinal2DLLImpl::Foo(int n)
{
std::cout << "Foo(n) is called" << std::endl;
return n * n;
}
void IFinal2DLLImpl::Release()
{
std::cout << "Release() " << std::endl;
delete this;
}
////////////////////////////////////////////////////////////////////////////////
FINAL2DLL_API FINAL2DLLHANDLE GetFinal(VOID)
{
std::cout << "GetFinal()" << std::endl;
return new IFinal2DLLImpl;
}
////////////////////////////////////////////////////////////////////////////////
FINAL2DLL_API INT FinalFoo(FINAL2DLLHANDLE handle, INT n)
{
INT nResult = -1;
if(handle)
{
nResult = handle->Foo(n);
}
return nResult;
}
FINAL2DLL_API VOID FinalRelease(FINAL2DLLHANDLE handle)
{
if(handle)
{
handle->Release();
}
}
|
Also, the corresponding dll project has stdafx.h, stdafx.cpp and targetver.h files.
The build is successful for this project. I copy Final2DLL.dll file to the main program's folder.
I try to link this dll with a simple code as follows:
Final2Test Project
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
//main.cpp
#include <Windows.h>
#include <iostream>
#include"Final2DLL.h"
int main ()
{
FINAL2DLLHANDLE handle = GetFinal();
if(handle)
{
FinalFoo(handle, 42);
FinalRelease(handle);
handle = NULL;
}
else
{
std::cout << "No run-time linking to the DLL" << std::endl;
}
return 0;
}
|
But, when I try to link this dll explicitly to a simple exe, I get the following errors.
error LNK2019: unresolved external symbol __imp__GetFinal@0 referenced in function _main
error LNK2019: unresolved external symbol __imp__FinalFoo@8 referenced in function _main
error LNK2019: unresolved external symbol __imp__FinalRelease@4 referenced in function _main
error LNK1120: 3 unresolved externals D:\bc913\cpp_project\Dynamic\Final2Test\Debug\Final2Test.exe 1
|
Also, I try with this code and it fails again with the same type of errors.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
//main2.cpp
#include <Windows.h>
#include <iostream>
#include"Final2DLL.h"
int main ()
{
FINAL2DLLHANDLE handle; //Function ptr
bool fFreeResult;
bool fRunTimeLinkSuccess = false;
//Get a handle to the DLL Module
HINSTANCE hDll = LoadLibraryA("Final2DLL.dll");
if(hDll)
{
handle = GetFinal();
//handle = (FINAL2DLLHANDLE)GetProcAddress(hDll, "GetFinal");
if(handle)
{
fRunTimeLinkSuccess = true;
FinalFoo(handle, 42);
FinalRelease(handle);
handle = NULL;
}
//Free the DLL Module
fFreeResult = FreeLibrary(hDll);
}
if(!fRunTimeLinkSuccess)
std:: cout << "No run-time linking to the DLL" << std::endl;
return 0;
}
|
How can I solve this problem? What is your expert opinion? (NOTE: When I also introduce Final2DLL.lib, it works but it is not what I want to do.)
2) Related with the question above, what is the best way to provide a "pure" explicit linking? How can I explicitly link a dll without introducing the corresponding .lib and without including the dll's header file?
I have been working on this topic for a long time and need an expert light.
Thanks in advance,