Silverfrost Forums

Welcome to our forums

Creating Executable file from DLL and OBJ files

27 May 2015 7:52 #16354

Apologize if this is a silly question.

[u:e7ea7b895d]What I am trying to do[/u:e7ea7b895d] I have 2 .for files Ex1.for and Ex2_Real.for. I have created a Ex2.dll from the Ex2_Real.for file. In the same directory as the Ex2.dll I also have Ex1.for compiled into a Ex1.obj file. I want to compile the Ex1.obj and the Ex2.dll files into a single executable file. In fact, theEx1 .obj has a call to the subroutine that was converted into the Ex2.dll file. I am doing this for testing the possibility of compiling our company's program into a dll file to be used by other 3rd party programs. We only want 1 of our routines to be a dynamic link, accessible at run time to 3rd parties. To mimic this I created 1 dll and 1 obj file. The obj file will not be accessible to the third party, while the dll will be shared with them and can be accessed, like a black box, without us revealing what is inside the dll.

However, I am missing something when trying to convert the .dll and .obj into a single executable file. For testing sake, I have kept the coding within Ex1 and Ex2 simple. Ex1 has 3 variables a, b, and c, where c = a+ b . Ex1 then calls Ex2 with the arguments a, b and c. Ex2 simply displays the output a, b, and c.

I created a Create.lk with the following 2 lines, load d:\...\Ex1.obj load d:\...\Ex2.dll file d:\...\Final.exe

I then created a CreateFinalExe.bat with slink d:\...\Create.lk

When I run CreateFinalExe.bat, I get a No main, WinMain or LibMain function. I dont have a programming background per se, or a computer science background either. I did some searching on the internet, but could not quite grasp what is exactly going on. Appreciate any help in this regard. Please correct me if any of my understanding is wrong, grossly or subtly.

27 May 2015 8:09 (Edited: 27 May 2015 8:12) #16355

Does Ex1.for contain a main program? When you built the DLL, what symbol(s) did you specify as being marked for export?

It would help if, in addition to (or instead of, as appropriate) giving verbal descriptions of what the source files contain, you posted the complete contents of the two files.

27 May 2015 8:12 #16356

Mecej4, Thank you for the quick response.

Here is the code in Ex1 subroutine Ex1 implicit none real * 8 a, b, c c a = 10.0d0 b = 15.0d0 c = a + b c write (6,*) 'I am from Ex1 - going to call Ex2' call ex2 (a, b, c) c stop end

and here is the code in Ex2 subroutine Ex2 (a, b, c) implicit none real * 8 a, b, c c write (6,) 'I am from Ex2 - Called from Ex1' write (6,) 'a =', a write (6,) 'b =', b write (6,) 'c =', c c return end

27 May 2015 8:14 #16357

You cannot build an EXE unless there is one and only one object that contains a main program.

In file Ex1.for, change 'SUBROUTINE' to 'PROGRAM', and rebuild the EXE.

27 May 2015 8:16 #16358

You can not take code from a DLL and link it into an exe.

A DLL is 'dynamic' which means that it links at load or run time.

There are basically three ways that work...

  1. Just link the original obj files and do not create a library.

  2. Create a static library rather than a DLL and use this in the linking process.

  3. Create a separate DLL and executable to be used together at run time.

27 May 2015 8:26 #16359

Mecej4, I changed Subroutine to Program, and rebuild the exe. I continue to get the same error 'No main, winmain...'

27 May 2015 8:28 #16360

PaulLaidler,

So if I understand right, I should only try to compile the Ex1.obj into an executable. Since I already have a dll of Ex2, I do not need to build an exe with it? So at run time, Ex1.obj can access the Ex2.dll without Ex2.dll having been compiled into the executable?

27 May 2015 8:37 #16361

You have to get all the pieces right, and you have to build in the proper order. You have to get the syntax correct. For example, you cannot use 'c' to start comment lines when the source is in free form.

File Ex2.f90:

subroutine Ex2 (a, b, c)
implicit none
real a, b, c
!
write (6,*) 'I am from Ex2 - Called from Ex1'
write (6,*) 'a =', a
write (6,*) 'b =', b
write (6,*) 'c =', c
!
return
end

Building DLL:

ftn95 ex2.f90
slink /dll ex2.obj /export:EX2

File Ex1.f90:

Program Ex1
implicit none
real a, b, c
!
a = 10.0d0
b = 15.0d0
c = a + b
!
write (6,*) 'I am from Ex1 - going to call Ex2'
call ex2 (a, b, c)
!
stop
end

Building and running EXE:

ftn95 ex1.f90
slink ex1.obj ex2.dll
ex1

Output:

 I am from Ex1 - going to call Ex2
 I am from Ex2 - Called from Ex1
 a =    10.00000
 b =    15.00000
 c =    25.00000
27 May 2015 9:03 #16362

Mecej4,

Thank you! I am able to get it all together now and see the output I desired.

Thanks very much for your help.

Anand

28 May 2015 2:45 #16363

Suppose I want to call a Fortran subroutine from a DLL. How would I do it. To revisit, I have 3 files now.

  1. Program Ex1.for which will create an executable Ex1.exe
  2. Subroutine Ex2.for compiled into a Ex2.dll
  3. Subroutine Ex3.for compiled into a Ex3.obj

I get an error 29, call to missing routine, even when I have compiled in Ex3.for as Ex3.obj and linked it with the Ex1.obj.

Once again, apologize if this is dumb question. Thank you for your help.

28 May 2015 3:23 #16364

Either link Ex3.obj with Ex2.obj into Ex2.dll or create Ex3.dll from Ex3.obj. The first option is simpler.

28 May 2015 3:30 #16365

Paul,

So, if I understand correct - all routines that a DLL file calls, should themselves be a DLL or should be compiled into the main DLL (which is independent).

28 May 2015 3:36 #16366

Anand, from your questions I conclude that you would benefit by reading some documentation on how DLLs and EXEs function and how they are put together.

Having read those, you would realize that once a DLL has been built, you cannot add new subprograms to it. If you changed EX2.FOR after building EX2.DLL, the DLL no longer corresponds to the source code. It is stale, and needs to be discarded and rebuilt.

There is one special case where things are a bit different: if the DLL contains a routine one of whose dummy arguments is EXTERNAL or a pointer to a routine, the code in the DLL will call whichever routine gets passed to the DLL routine as an actual argument -- the actual argument in such cases is sometimes called a callback routine.

28 May 2015 3:50 #16367

Mecej4,

If there are any links you could direct me to apart from what is available in FT95 help, I will be thankful.

Yes, I did indeed rebuild my Ex2.dll after I made changes to Ex2.for. Since Ex3 is being called by Ex2.dll, I attempted to link Ex3.obj into Ex2.dll but cannot seem to get around the problem of error 29.

28 May 2015 4:05 #16368

IF EX2.for contains a call to a routine that is in EX3.for, you could not have built EX2.DLL without linking in EX3.obj when building the DLL -- the link command for building the DLL would have failed, telling you about unsatisfied externals that were responsible. We do not know what is in EX3.for and how you rebuilt the DLL, so it is not possible to be more specific.

You cannot add .OBJ files to a DLL. Unlike a static library, a DLL cannot contain unresolved references to external routines. In many ways, a DLL is more similar to an EXE than a LIB file.

Start with the Wikipedia article on DLLs: http://en.wikipedia.org/wiki/Dynamic-link_library , and see some of the links at the bottom of that page.

28 May 2015 6:42 #16369

Mecej4,

Thanks again. In Ex1.for I have

  winapp 300000,600000
  Program Ex1
  implicit none
  real * 8 a, b, c
  a = 11.0d0
  b = 15.0d0
  c = a + b
  write (6,*) 'I am from Ex1 - going to call Ex2'
  call ex2 (a, b, c)
  stop
  end
  

In Ex2.for I have,

  subroutine Ex2 (a, b, c)
  implicit none
  real * 8 a, b, c
  call Ex3(a, b, c)
  write (6,*) 'I am from Ex2 - Called from Ex1'
  write (6,*) 'a =', a
  write (6,*) 'b =', b
  write (6,*) 'c =', c
  return
  end
  

In Ex3.for I have simple code to do c = a*b

  subroutine Ex3 (a, b, c)
  implicit none
  real * 8 a, b, c
  write (6,*) 'I am from Ex3 - Called from Ex2'
  c = a*b 
  write (6,*) 'c is now a product', c
  return
  end

I used the following statements to create a DLL out of Ex2.for and Ex3.for Ftn95 D:\...Ex2_Real.For /link D:\.....\Ex2.dll Ftn95 D:\.....\Ex3.for /link D:\.....\Ex3.dll

Next I linked the main program Ex1.for with the two DLLs Ftn95 D:\....\Ex1.for slink D:\....\Ex1.obj D:\....\Ex2.dll D:\.....\Ex3.dll

I do not get any errors while compiling. Once the exe file, Ex1.exe has been created, and I open it, I crash in Ex2 with an error 29. Also, in the call stack, i see a [recur=1] . Is this an indication of something being called recursively?

28 May 2015 7:02 #16370

What is in Ex2_real.for?

This works for me:

ftn95 ex2.f90
ftn95 ex3.f90
slink /dll ex2.obj ex3.obj /export:EX2
ftn95 ex1.f90
slink ex1.obj ex2.dll
ex1
28 May 2015 7:26 #16371

the subroutine named as Ex2 is saved with file name Ex2_real.for

However, after doing the changes as you suggested, I still crash in the same location, that Ex3 is missing. I see no errors during compilation of the ex2 and ex3 into a DLL. I am missing something then with creating the executable?

28 May 2015 7:36 #16372

This is exactly what I have

Ftn95 D:\...\Ex3.for D:\...\Ex3.obj Ftn95 D:\...\Ex2_Real.for D:\...\Ex2_Real.obj slink /dll D:\...\Ex2_Real.obj D:\...\Ex3.obj /export:EX2 Ftn95 D:\...\Ex1.for slink D:\...\Ex1.obj D:\...\Ex2.dll

I see no errors when I compile this.

28 May 2015 9:48 #16373

What do you actually have in place of the '\...\' in your post? Secondly, are you compiling in a working directory different from the directory containing the source files? Are you placing the resulting OBJ files in a third directory?

By default, when you name only the source file, the corresponding object file is placed in the current working directory.

Unless there is a need to use more than one directory, and until you become familiar with the process, I suggest that you keep all the files related to the project in a single directory, and that you delete all old versions of .OBJ, .DLL and .EXE files before rebuilding. Otherwise, there will be much scope for confusion, mistakenly using old versions of objects and DLLs, etc.

Please login to reply.