Explicit Linking of DLL

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,
The functions in Final2DLL.cpp need to be declared in Final2DLL.h
Yes, I've just declared them at line #34,41 and 43 with EXTERN_C definitions...
Since you're linking at runtime, you also have to load in the functions at runtime. The program has no idea where it's supposed to get the functions you're specifying.

Check out this tutorial, it's great:
http://www.cplusplus.com/articles/48TbqMoL/
Last edited on
Sorry I missed those declarations. I copied over all of your files though and it works if I comment out all of dllmain.cpp

Why do you even have that file? It has one function that always returns true.
Last edited on
I did get a warning forFinal2DLL.h here:
1
2
3
4
5
#ifdef FINAL2DLL_EXPORTS
#define FINAL2DLL_API __declspec(dllexport)
#else
#define FINAL2DLL_API __declspec(dllimport)
#endif 


You're defining it either way, so just define it once and get rid of the if..else
@Avilius=> Thanks for the article, it seems well. I will check it and try to implement.

@Yay295 => What happens if I only dllexport? I think that part is fine. Right?
Yep. I don't get any errors with only dllexport.
@Avilius: Regarding to my 2nd question, I've already checked the article in detail.

In that project, still I ended up with the corresponding dll's header file (main.hpp) in the main application.

The thing I want to do is to be able to call dll w/o any corresponding header file. Maybe, I demand too much things or unfeasible approach!

To sum up, my final purpose is to develop a software with 2 modules.
1) 1st one the core module and gets some inputs from the user.
2) 2nd module is a solver module. Based on the user inputs, it will implement one or more mathematical calculations (matrix process usually).
2.a) Here the dll comes into to the picture. For each specific math calculations, the solver module will call the corresponding dll.
2.b) This (these) dll(s) will execute some calculations on the inputs.

When I redesign or redevelop the actual dll, I don't want to recompile solver module again. That's why I don't get along with dll's header files.

It is a good approach? If not what kind of solutions I can implement?


Topic archived. No new replies allowed.