Trouble in calling subroutines within a dll

Hello everyone,

Note: I had this posted in beginner's forum, but thought this is the appropriate location.

I am new to C++ and the whole Object oriented programming. As such I am learning by experimenting. I am having some trouble resolving a few errors I am having.

I am using a dll written in FORTRAN to do some calculations and here is how I have set up the program. I have created following files:

C++ source files:
main.cpp
File1.cpp

Header Files:
Datamain.h
DataFile1.h
DataCalcdll.h
File1.h

Dll:
Calc.dll

I have two subroutines in the dll:
Sub1dll()
Sub2dll()

Here is how the source code looks:

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//Datamain.h
//----------
#ifndef DATAMAIN_H_
#define DATAMAIN_H_

#pragma once

class Datamain
{
public :
 static int Index;
};
#endif

//DataCalcdll.h
//-------------
typedef void (__stdcall *fp_Sub1dllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long );
typedef void (__stdcall *fp_Sub2dllTYPE)(double &,double &,double *,long &,double &,double &,double &,double &,double &,double &,long &,char*,long );

fp_Sub1dllTYPE Sub1dll;
fp_Sub2dllTYPE Sub2dll;

//DataFile1.h
//-----------
#ifndef DATAFILE1_H_
#define DATAFILE1_H_

    static const long charlength=255;
    static const long filepathlength=255;
    static const long lengthofreference=3;
    static const long errormessagelength=255;
    static const long nmax=20;
    static const long numparams=72;
    static const long maxcoefs=50;

    static char Name[charlength*nmax];
    static char reference[lengthofreference+1];
    static char herr[errormessagelength+1];
    static char hf[charlength+1];

#endif

//File1.h
//-----------
#ifndef DATAFILE1_H_
#define DATAFILE1_H__H_

#pragma once

#include <windows.h>

class File1
{
public:
  static void Loaddll();
  static void Setup(int Num);
};
#endif

//main.cpp
//--------
#include <iostream>
#include <stdio.h>
#include "Datamain.h"
#include "File1.h"
#include "DataFile1.h"

int Datamain::Index;

using namespace std;

int main()
{
     Datamain::Index = 3;
     File1::Setup(Datamain::Index);
     Sub2dll();
}

//File1.cpp
//---------
#include <string>
#include <iostream>
#include <stdio.h>
#include "DataFile1.h"
#include "File1.h"
#include "DataCalcdll.h"

using namespace std;

void File1::Loaddll()
{
// First create a pointer to an instance of the library
// Then have windows load the library.
   HINSTANCE dllInstance;
//This looks only in the current directory for dll
   dllInstance = LoadLibrary("./Calc.dll");

// Then get pointers into the dll to the actual functions.
	Sub1dll = (fp_Sub1dllTYPE) GetProcAddress(dllInstance,"Sub1dll");
	Sub2dll = (fp_Sub2dllTYPE) GetProcAddress(dllInstance,"Sub2dll");
}

void File1::Setup(int Num)
{

	Sub1dll();

//	Sub2dll();
}


Here are my questions:

1) I actually want to call Sub2dll from the main program. But the above program does not build and it gives me the following error:
In function 'int main()': Sub2dll was not declared in this scope.

When I build this program with the call to Sub2dll in main commented out and instead put that call in File1::Setup function things build well and runs giving the answer expected. How can I make the call to Sub2dll from main.

2) I am including "Datamain.h" in main. However when I build it with out the declaration int Datamain::Index; in main, it gives me the following error:
undefined reference to Datamain::Index
When I add that declaration to main the error disappears.

I am usiing Code::blocks with MinGW compiler. I have not put the argument list for the subroutine calls since there were not errors in that part.

Any help on this matter is greatly appreciated and I look forward to great tips and help from fellow forum mates.

Regards
Sankar
Last edited on
You declared your function pointers in datacalcdll.h (lines 20,21).
main.cpp doesn't include datacalcdll.h, therefore the function pointers are undefined.

You should really not define the function pointers in a .h file. You'll get multiply defined symbols at link time if you include the header in multiple .cpp files.

You should declare the function pointers as extern in the .h file.
1
2
extern fp_Sub1dllTYPE Sub1dll;
extern fp_Sub2dllTYPE Sub2dll;


Then define the function pointers in main.cpp:
1
2
fp_Sub1dllTYPE Sub1dll;
fp_Sub2dllTYPE Sub2dll;


Thank you AbstractionAnon. I will try the solution and will post what I find. Meanwhile is there any good reference material on how to use all these various concepts. The problem is I am getting this dll from an external entity and they gave a sample C++ program and the problem is that the xample contained only one source file, containing only int main() (with one header file DataCalcdll.h which is included in main cpp file. Now when I try to rip it apart and use various functions from various cpp files, I am lost.

Thanks you for the help.
There are two ways to link to functions in a DLL. Static binding and dynamic loading.

With static binding, the references from your calls are resolved to the DLL at link time. All you need to do with static binding is specify the DLL to the linker. Here's a good tutorial on static linking:
http://msdn.microsoft.com/en-us/library/vstudio/ms235636.aspx
As long as you have the proper function declarations, the linker will resolve the calls. Static linking is appropriate when you know the DLL at build time.

With dynamic loading (what you're doing), you open the DLL at run time, search it for the entry point you want, then call the entry point. The trick here is that you need to declare the external function as a function pointer with the correct signature. You did this with your typedef and your declaration of the function pointers. Assign the void pointer returned by GetProcAddress() via a cast to the function pointer, then call the function via the function pointer. Dynamic loading is useful when you want to determine the specific DLL at run time.

The only problem I saw with what you did was the lack of visibility of the function pointers in your main where you made the call.
Topic archived. No new replies allowed.