C++ program calls template function inside DLL

Hello you all!

I'm trying to pass parameters to a DLL-Funktion and get a return-value from it. My code does not return any Error-Message. But it does not work.

The problem is, that the function pointer (DLL_Add_Funkt) does not works. I'm compiling on Windows with Code-Blocks.

Does any one knows the problem?
Here the very simple complete code:


Filename: Calls_dll.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
#include <iostream>
#include <windows.h>

int main()
{
   typedef int(__stdcall * DLL_FUNK)(int,int);
   DLL_FUNK DLL_Add_Funkt;

   HINSTANCE DLL_Bibliothek = LoadLibrary("DLL_funk.dll");

   if(DLL_Bibliothek)
   {
        std::cout << "Wounderfull!" << "\n";

        DLL_Add_Funkt = (DLL_FUNK)GetProcAddress(DLL_Bibliothek, "Add");

        if(DLL_Add_Funkt)
        {
            std::cout << "Puntero colocado con exito...! "<< "\n";
            //DLL_Add_Funkt();
        }

        FreeLibrary(DLL_Bibliothek);
   }
   else
   {
      std::cout << "Upsss... Something gets really wrong..."
                << std::endl;
   }

   //getchar();
   return 0;
}


DLL Projekt (2 Files):
Filename: dll_function.cpp

1
2
3
4
5
6
7
8
#include "dll_header.h"
#include <iostream>

DLLEXPORTDIR int Add(int a, int b)
{
    std::cout << "Hello" << "\n";
    return( a + b );
}


Filename: dll_header.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef _DLLWHITHTEMPLATES_H_
#define _DLLWHITHTEMPLATES_H_

    #define DLL_EXPORT

    #ifdef DLL_EXPORT
        #define DLLEXPORTDIR __declspec(dllexport) __stdcall
    #else
        #define DLLIMPORTDIR __declspec(dllimport)
    #endif


    DLLEXPORTDIR int Add(int a, int b);

#endif 


The name of the files created by the dll-Projekt are:
DLL_funk.dll
DLL_funk.a
DLL_funk.def


The DLL_funk.dll file is in the same folder of Calls_dll.exe created by compiling Calls_dll.cpp.

DLL_Add_Funkt is always 0!

Has someone some idea?
Thanks for any help!
Last edited on
You should always check errors in C.

If you look at msdn you can find when you need to check GetLastError after a function.

But GetLastError is only a number so to read it use this

https://stackoverflow.com/questions/1387064/how-to-get-the-error-message-from-the-error-code-returned-by-getlasterror

I should also add in that its my bad that I only used dll exports using extern "C" {}.
Last edited on
Hello you all!

I could found the problem. It was the name of the function. It has to be the real name, or inside the dll files there has to be declared extern "C". Here the code for those with similar problems or questions:


Filename: Calls_dll.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
#include <iostream>
#include <windows.h>

int main()
{
   typedef int(__stdcall * DLL_FUNK)(int,int);
   DLL_FUNK DLL_Add_Funkt;

   HINSTANCE DLL_Bibliothek = LoadLibrary("DLL_funk.dll");

   if(DLL_Bibliothek)
   {
        std::cout << "Wounderfull!" << "\n";

        DLL_Add_Funkt = (DLL_FUNK)GetProcAddress(DLL_Bibliothek, "Add@8"); 
        // Example for a real name of a function in a DLL-file.
        // This name is changing always by recompiling the DLL project. 
        // It can be figures out by
        // special programs created for this. For example:
        // http://www.dependencywalker.com/

        if(DLL_Add_Funkt)
        {
            std::cout << "Pointer successfully defined...! "<< "\n";
            //DLL_Add_Funkt();
        }

        FreeLibrary(DLL_Bibliothek);
   }
   else
   {
      std::cout << "Upsss... Something gets really wrong..."
                << std::endl;
   }

   //getchar();
   return 0;
}


DLL Projekt (2 Files):
Filename: dll_function.cpp

1
2
3
4
5
6
7
8
#include "dll_header.h"
#include <iostream>

DLLEXPORTDIR int Add(int a, int b)
{
    std::cout << "Hello" << "\n";
    return( a + b );
}


Filename: dll_header.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef _DLLWHITHTEMPLATES_H_
#define _DLLWHITHTEMPLATES_H_

    #define DLL_EXPORT

    #ifdef DLL_EXPORT
        #define DLLEXPORTDIR __declspec(dllexport) __stdcall
    #else
        #define DLLIMPORTDIR __declspec(dllimport)
    #endif


    DLLEXPORTDIR int Add(int a, int b);

#endif 


Now I have a new question. Is it possible to have a template-Funktion in a dll-File?
It seems not to be possible because the datatype has to be defined at compiler timer.


Here the code:

Filename: Calls_dll.cpp (the same file)
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
#include <iostream>
#include <windows.h>

int main()
{
   typedef int(__stdcall * DLL_FUNK)(int,int);
   DLL_FUNK DLL_Add_Funkt;

   HINSTANCE DLL_Bibliothek = LoadLibrary("DLL_funk.dll");

   if(DLL_Bibliothek)
   {
        std::cout << "Wounderfull!" << "\n";

        DLL_Add_Funkt = (DLL_FUNK)GetProcAddress(DLL_Bibliothek, "????");

        if(DLL_Add_Funkt)
        {
            std::cout << "Pointer successfully defined...! "<< "\n";
            //DLL_Add_Funkt();
        }

        FreeLibrary(DLL_Bibliothek);
   }
   else
   {
      std::cout << "Upsss... Something gets really wrong..."
                << std::endl;
   }

   //getchar();
   return 0;
}


DLL Projekt (2 Files):
Filename: dll_function.cpp (now with template)

1
2
3
4
5
6
7
8
#include "dll_header.h"
#include <iostream>

template<typename T>
DLLEXPORTDIR T Add(T a, T b)
{
    return(a + b);
}


Filename: dll_header.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef _DLLWHITHTEMPLATES_H_
#define _DLLWHITHTEMPLATES_H_

    #define DLL_EXPORT

    #ifdef DLL_EXPORT
        #define DLLEXPORTDIR __declspec(dllexport) __stdcall
    #else
        #define DLLIMPORTDIR __declspec(dllimport)
    #endif


        template<typename T>
        DLLEXPORTDIR T Add(T a, T b);

#endif 


Thanks for any information!
Last edited on
Now I have a new question. Is it possible to have a template-Funktion in a dll-File?
It seems not to be possible because the datatype has to be defined at compiler timer.


Context is everything in answering this question.

If the types are declared in the DLL, sure. The template can fully instantiate a type defined in the DLL's code. So, in your example, if a type is defined in dll_header.h, and the template code is defined there, then that template can be instantiated in dll_function.cpp and called from ithin dll_function.cpp.

Further, if that type is used in the code loading and consuming the dll, then that code can call the functions of the template code built in the dll.

To be clear, this would mean those functions would have to be exported under those conditions, or the template code would have to be entirely inline in the includes used to interface to the dll.

You are correct to assume, however, that if those types are not exposed to the code consuming the dll, and if the template code is not exported where function calls are created, then the code consuming the dll could not reach the template code.

To put this another way, fitting a slightly different context, say a custom container similar to a stack is created as template code, and is entirely placed in a header. Both the DLL code and the code consuming the DLL include that header. They both instantiate the template. There may be code built inside the DLL for that stack template, and there will be duplicate code built in the consumer of the DLL. The two will not mix or conflict if the DLL doesn't export the duplicates.

Most modern use of templates are "header only" code. If both the consumer of the DLL and the DLL itself include that template, there may be duplicate code, but that code should be compatible. There can be memory allocation questions about what is allocated inside the DLL and then passed to the consumer, or vica versa, and if there were any static or global data involved, that could be an issue (there would likely be duplicates there, too).



Topic archived. No new replies allowed.