Silverfrost Forums

Welcome to our forums

Creating Executable file from DLL and OBJ files

29 May 2015 1:56 #16377

Mecej4,

I was successful in compiling and executing, when I renamed my Ex2_real to Ex2. I am surprised at that, because when I was using Ex2_real I made sure all of the compilation code used Ex2_real.

I am compiling and working in the same directory. My source files are all in the same directory as the directory I am trying to compile in. I am not using a third directory to place the object/dll or exe files.

I used the \...\ for the sake of brevity in my posts. I have removed all the directory path names now.

My compilation code is now Ftn95 Ex2.for Ftn95 Ex3.for slink /DLL Ex2.obj Ex3.obj /export:EX2 Ftn95 Ex1.for slink Ex1.obj Ex2.dll

29 May 2015 2:11 #16378

All right, now that you have explained what you did, I see why your earlier attempt failed. When you link a number of object files, the name of the resulting EXE or DLL file is obtained from the first listed object file, unless you use the /OUT:xxxx option. Specifically, the command

slink /dll Ex2_Real.obj Ex3.obj /export:EX2 

would have produced EX2_REAL.DLL, so an attempt to use EX2.DLL in a subsequent link would fail because EX2.DLL did not exist or was an older and probably incompatible version.

29 May 2015 2:14 #16379

I did use Ex2_Real.DLL, which is why I am not sure what I missed. If Ex2.Dll was in my compile program but not found in the directory, then I would have received an error during compilation. I did not receive any error during compilation. Not sure what I did wrong. However, I think for now I have a working solution. Thank you so much for your patience with a rookie.

29 May 2015 6:54 #16380

As I continued to work, I realize there is something very specific about the names of the routines and the DLLs or the way they interact.

I have 3 routines now. 1 program called DriverProgram and 2 routines called GetK.for and Ex3.for. I want to combine GetK and Ex3 into 1 DLL and then link with the DriverProgram to create DriverProgram.exe

When I compile this, with Ftn95 D:\Development\GetK.for Ftn95 D:\Development\Ex3.for slink /DLL D:\Development\GetK.obj D:\Development\Ex3.obj /export:GetK Ftn95 D:\Development\DriverProgram.for slink D:\Development\DriverProgram.obj D:\Development\GetK.dll

I get an error Warning: the following symbols are missing: GetK

I am not sure why GetK is missing.

29 May 2015 7:39 #16381

I figured this out, and it is quite amazing what I figured.

in the line

slink /DLL D:\Development\GetK.obj D:\Development\Ex3.obj /export:GetK

if you replace export:GetK with export:GETK

no more compiler warnings. The name after export must be UPPER CASE. I am very sure based on my trials today. Irrespective of the name in the directory. Strangely in the directory, it shows up as GetK.dll

It was providential I found this.

29 May 2015 9:15 #16382

In instructions for using SLINK you will find /exportall and this is usually preferred.

1 Jun 2015 2:52 #16393

Thank you Paul. Is there a restriction on the number of obj files that can be exported into 1 DLL? I seem to have trouble converting more than 2 obj files into 1 DLL.

1 Jun 2015 3:48 #16395

No. There is no significant restriction.

1 Jun 2015 6:54 #16397

I seem to have trouble converting more than 2 obj files into 1 DLL Please state what 'trouble' you had. I have one DLL which was built out of more than 500 OBJ files with no problems at all, and many other similar DLLs built out of fewer OBJ files (such as 5 to 10).

1 Jun 2015 7:48 #16399

To give you an example,

I have 1 DriverProgram (this is a program) and 3 subroutines (.for)

Program DriverProgram.for has a call to the following GetK.for that calls Ex3.for Dummycall.for that calls Ex3.for

So if I understand correct, I have to create one DLL out of GetK.obj and Ex3.obj as well as a second DLL out of Dummycall.obj and Ex3.obj

Next, I can link the program DriverProgram.obj with both the individual DLLs. Correct?

Will I be better off trying to create 3 DLLs, 1 each with GetK.for, Ex3.for and Dummycall.for and then linking all three DLLs with the main DriverProgram? I have tried this and failed.

1 Jun 2015 10:18 #16400

Quoted from anand3162 To give you an example,

I have 1 DriverProgram (this is a program) and 3 subroutines (.for)

Program DriverProgram.for has a call to the following GetK.for that calls Ex3.for Dummycall.for that calls Ex3.for

So if I understand correct, I have to create one DLL out of GetK.obj and Ex3.obj as well as a second DLL out of Dummycall.obj and Ex3.obj

I don't know the basis of your understanding. You can create zero, one, two or three DLLs. Note the zero. You are not required to create any DLLs.

Next, I can link the program DriverProgram.obj with both the individual DLLs. Correct?

Again, you can but you are not required to do this.

Will I be better off trying to create 3 DLLs, 1 each with GetK.for, Ex3.for and Dummycall.for and then linking all three DLLs with the main DriverProgram? I have tried this and failed.

'Better off' in what regard? What did you try, what commands did you use, and why did the attempt fail? Surely, you did not mean to ask if you are better off because you failed?

2 Jun 2015 2:31 #16402

Mecej4,

You are indeed right about 0 Dlls. However, my intent is to share our program with a 3rd party program via a DLL. Unfortunately, I cannot post my code as such, so I have been working up parallel example/drawing board kind of programs that I can post without worrying about IP.

Therefore, my questions were based on having decided I want to share my program with a 3rd party through a DLL. Here is the code that I used, that was successful.

FTN95 D:\Development\GetK.for FTN95 D:\Development\Ex3.for FTN95 D:\Development\Ex4.for FTN95 D:\Development\Dummycall.for slink /DLL D:\Development\Dummycall.obj D:\Development\Ex4.obj D:\Development\Ex3.obj /export:DUMMYCALL slink /DLL D:\Development\GetK.obj D:\Development\Ex3.obj D:\Development\Ex4.obj /export:GETK Ftn95 D:\Development\DriverProgram.for slink D:\Development\DriverProgram.obj D:\Development\Dummycall.dll D:\Development\GetK.dll

Though my attempt succeeded, just wanted to know if I did get my bearings right?

3 Jun 2015 1:42 #16409

Quoted from anand3162 ...Here is the code that I used, that was successful.

FTN95 D:\Development\GetK.for FTN95 D:\Development\Ex3.for FTN95 D:\Development\Ex4.for FTN95 D:\Development\Dummycall.for slink /DLL D:\Development\Dummycall.obj D:\Development\Ex4.obj D:\Development\Ex3.obj /export:DUMMYCALL slink /DLL D:\Development\GetK.obj D:\Development\Ex3.obj D:\Development\Ex4.obj /export:GETK Ftn95 D:\Development\DriverProgram.for slink D:\Development\DriverProgram.obj D:\Development\Dummycall.dll D:\Development\GetK.dll

Though my attempt succeeded, just wanted to know if I did get my bearings right?

You have only given file names, so 'here is the code' is a yet-to-be-kept commitment. In the circumstances, the best I can say is 'you may have got your bearings right'. I certainly have no interest in seeing your proprietary code, and it is up to you to ensure that whatever code examples you present here preserve the issues that are suspected to be obstacles in the big code.

3 Jun 2015 3:59 #16411

Mecej4,

Here is the code. I have not changed much of it from my earlier dabbles.

  winapp 300000,600000
  Program DriverProgram
  implicit none
  double precision Temperature, Pressure, Z(10), K(10)
  integer I
  Temperature = 300.0d+00
  Pressure = 1.01d+05
  Z(1) = 0.50d+00
  Z(2) = 0.25d+00
  Z(3) = 0.20d+00
  Z(4) = 0.05d+00
  Z(5:10) = 0.0d+00
  K = 0.0d+00
  write (6,*) 'Main driver program calling Kvalues'
  write (6,*) '.................................'
  call GetK(Temperature, Pressure, Z, K)
  write (6,*) '.................................'
  write (6,*) 'Back to Driver Program'
  write (6,*) 'Kvalues are as follows'
  do I = 1, 10
    write (6,*) 'Kvalue-',I
    write (6,*) ' ',K(I)
  enddo
  call Dummycall(Temperature, Pressure, I)
  stop
  end
  
  subroutine Dummycall (a, b, c)
  implicit none
  real * 8 a, b, c
  write (6,*) 'I am from Dummy_call - Called from MainProgram'
  call Ex3(a, b, c)
  return
  end
  
  subroutine Ex3 (a, b, c)
  implicit none
  real * 8 a, b, c
  write (6,*) 'I am from Ex3 - Called from Ex2'
  call Ex4(a, b, c)
  return
  end
  
  subroutine Ex4 (a, b, c)
  implicit none
  real * 8 a, b, c
  write (6,*) 'I am from Ex4 - Called from Ex2'
  return
  end
  
  subroutine GetK(Temperature, Pressure, Z, K)
  implicit none
  double precision Temperature, Pressure, Z(10), K(10)
  integer I
  write (6,*) 'I am from GetKvalues'
  do I = 1, 10
    K(I) = Temperature*Pressure*Z(I)*1.d-05
  enddo
  call Ex3(Temperature, Pressure, I)
  write (6,*) 'Exiting GetKvalues'
  return
  end

I do acknowledge that, I can combine ALL the subroutines into 1 .for file and make a DLL of that .for. However, my actual programs are all several thousand lines, so that makes code maintenance troublesome.

My objective here is to make the routine DummyCall and GetK as 2 separate DLLs. For example, make GetK.dll without linking Ex3.obj and GetK.obj using slink. I am trying to recreate a situation where in my actual program, a DLL should be able to call other routines (that are not DLLs). Maybe I am doing something outright wrong.

3 Jun 2015 5:05 #16412

Quoted from anand3162

I do acknowledge that, I can combine ALL the subroutines into 1 .for file and make a DLL of that .for. However, my actual programs are all several thousand lines, so that makes code maintenance troublesome.

My objective here is to make the routine DummyCall and GetK as 2 separate DLLs. For example, make GetK.dll without linking Ex3.obj and GetK.obj using slink. I am trying to recreate a situation where in my actual program, a DLL should be able to call other routines (that are not DLLs). Maybe I am doing something outright wrong. Much of your confusion and doubt is attributable to loose usage of terms, which could be an indication of incomplete understanding of the underlying concepts. For example, take 'routines (that are not DLLs)'. A routine is never a DLL, just as a scratch is never a cat! DLL stands for Dynamic Link Library, and the term has a well-defined set of attributes. For the purposes of this thread, it is just a library. You can put any previously compiled routines of your choice into a DLL, other than a main program. You may then use these DLLs to build other DLLs or EXEs, just as you would use static libraries, which we could abbreviate as SLLs. Once DLLs and SLLs have been produced, they can be used in similar ways, and they are almost interchangeable.

I have placed a call-graph of your program at https://www.dropbox.com/s/oqawfp8nu6fbihs/cgraph.png?dl=0 . If you and I can agree on the following ground rules, we can infer the ways in which we can structure the DLL preparation: (i) no routine shall be placed in more than one DLL; (ii) only symbols that are required outside the DLL will be exported, and (iii) the number of routines placed in a DLL is decided on the basis of user preferences (as yet unstated!).

Looking at the call graph leads me to place EX3 and EX4 into one DLL, followed by placing GETK and DUMMYCALL into one DLL each. Assuming that each routine has been placed in a separate source file and compiled, here are the linking commands:

slink /dll Ex3.obj Ex4.obj /export:EX3
slink /dll getk.obj ex3.dll /export:GETK
slink /dll Dummycall.obj ex3.dll /export:DUMMYCALL
slink DriverProgram.obj getk.dll dummycall.dll

I tested the resulting DriverProgram.exe, and it ran fine.

3 Jun 2015 10:40 #16414

Mecej4,

Very thankful for your patience and help. Yes, I agree with the call graph that you have uploaded to dropbox. That drawing really clarified the point you have been trying to beat across for several days to me, finally! Once I saw the drawing and how you linked bottom up starting from Ex3 and working your way up the call graph, it made sense to me. Thanks so much again for helping.

3 Jun 2015 10:59 #16415

Had the call graph been a simple tree (a banyan tree is not simple), some of the issues that your example raised would have been absent. There would have been no multiple paths through the tree, for example, and the question of putting the object code for a routine in more than one DLL would not have arisen.

A call graph can be helpful in other ways. It can guide you when writing a makefile for building a complex project with multiple dependencies.

4 Jun 2015 3:01 #16421

Mecej4,

Totally agree with what you say, and I have been doing call graphs now to make life easier. Thank you for steering me in the right direction.

4 Jun 2015 9:25 #16423

I want to use some common memory variables in my program. I have a common block in my main routine and define a value for the common memory variables in the main routine. This main routine along with its dependencies is converted into a DLL. Is there a way another DLL can access this common memory variable?

4 Jun 2015 10:42 #16424

It is possible, by creating a shared data segment. However, getting this to work correctly in a multithread or multiprocessor program is a bit complicated, particularly if more than one of the DLLs can update the shared data. So unless you absolutely need it, I suggest finding other ways of sharing data.

See https://software.intel.com/en-us/forums/topic/290141 , for example.

Please login to reply.