Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

tie a dll to my exe

Brian_Allison
Beginner
2,595 Views
I have a program that was compiled in IFC. I am using a new licensing software program that creates a dll that needs to be integrated into my code. How do I integrate the dll into my code, so that it know it has to have that dll in order to run?
0 Kudos
18 Replies
mecej4
Honored Contributor III
2,595 Views
Unless you manage the loading and unloading of DLLs in your program, the standard approach is to use the export library that is built along with the DLL. Link your application with the export library, and the dependency on the DLL will be embedded in your EXE.
0 Kudos
Brian_Allison
Beginner
2,595 Views
THe dll is provided to me after I go onto a website and create the licensing scheme that I want. I do not have a .lib file. THey say that I need to integrate the dll into my program.
0 Kudos
bmchenry
New Contributor II
2,595 Views
i think what they mean for you to do isto add the dll to the resouce section of your solution/project.
Then when you compile/link (hopefully) anycalls to the dll will be resolved.
0 Kudos
Steven_L_Intel1
Employee
2,595 Views
No, that won't work. You can't link against a DLL directly.

What is needed here is to use the Windows API routines LoadLibrary and GetProcAddr to load the DLL, look up the routines, and then call the routines through pointers. There is an example of this in the sample DLL\DynamicLoad. You will need to know if the routines being called expect the STDCALL calling mechanism.
0 Kudos
Brian_Allison
Beginner
2,595 Views
Like this, cause it does not work.

relap5$(NM).exe : lib\envrl$(NM).lib lib\graphics.lib \
lib\matpro$(NM).lib lib\relap$(NM).lib relap\relap5.$O \
lib\scdap$(NM).lib tpfh2o$(NM) tpfd2o$(NM) lib\filechk.dll
relap5$(NM).exe : lib\envrl$(NM).lib lib\graphics.lib \ lib\matpro$(NM).lib lib\relap$(NM).lib relap\relap5.$O \ lib\scdap$(NM).lib tpfh2o$(NM) tpfd2o$(NM) lib\filechk.dll

$(f90) -nologo $(FFLAGS) $(FPSTOP) $(FL) -libs:qwin \
relap\relap5.$O lib\relap$(NM).lib lib\scdap$(NM).lib \
lib\matpro$(NM).lib lib\relap5l.lib \
lib\envrl$(NM).lib lib\graphics.lib \
lib\libifcoremt.lib lib\libifport.lib lib\libifcoremt.lib \
lib\libifport.lib lib\libmmt.lib lib\kernel32.lib \
lib\ifqwin.lib gdi32.lib lib\user32.lib lib\libirc.lib \
comdlg32.lib ifqw_mdi.lib lib\libcmt.lib lib\imagehlp.lib \
lib\opengl32.lib lib\glu32.lib lib\f90gl.lib lib\f90glu.lib \
lib\f90glut.lib lib\glut32.lib \
-link -out:bin\relap5.exe -heap:1000000000 -stack:14000000 \
-incremental:no -nodefaultlib
0 Kudos
Steven_L_Intel1
Employee
2,595 Views
No - that doesn't work. See my reply just before yours.
0 Kudos
Paul_Curtis
Valued Contributor I
2,595 Views
Sample showing how to associate a DLL into F90:

[bash]LOGICAL FUNCTION MAPIBind() result (bOK)
    USE kernel32, only: LoadLibrary, GetProcAddress     ! was dfwin

    hMapiLib = LoadLibrary("mapi32.dll"C)
    IF (hMapiLib /= 0) THEN
        bOK = .true.
        lpMAPIInitialize= GetProcAddress(hMapiLib,"MAPIInitialize"C)
        bOK = bOK .AND. (lpMAPIInitialize /= 0)
        lpMAPIUninitialize= GetProcAddress(hMapiLib,"MAPIUninitialize"C)
        bOK = bOK .AND. (lpMAPIUninitialize /= 0)
        lpMAPILogon    = GetProcAddress(hMapiLib,"MAPILogon"C)
        bOK = bOK .AND. (lpMAPILogon /= 0)
        !... and many more
    END IF

END FUNCTION MAPIBind


SUBROUTINE MAPIUnBind()
    USE kernel32, only: FreeLibrary     ! was dfwin
    INTEGER :: rval
    IF (hMapiLib /= 0) rval = FreeLibrary(hMapiLib)
END SUBROUTINE MAPIUnBind
[/bash]

hMapiLib is INTEGER(HANDLE) and module-local.
0 Kudos
Brian_Allison
Beginner
2,595 Views
Does it help if I got the .lib file associated with the dll?
0 Kudos
Brian_Allison
Beginner
2,595 Views
I am not really a fortran programmer. I just handle the licensing and protection of the software. Our main programmer is out of town and I cannot reach him.
Our previous licensing software was easier, but limited to windows. Our new licensing software that we are trying out works on Windows, Mac, and Linux. The coding that you provided means nothing to me. Is there someway with the .lib and the .dll file that we can make this work.
0 Kudos
Steven_L_Intel1
Employee
2,595 Views
If you have the lib, yes. You can try this.... Attached to this post is a ZIP file containing MAKILIB.EXE. Extract this to a folder containing the DLL. Open a command prompt window and set default (CD) to that folder. Type:

makilib yourdll.dll

This will create a .lib that can be linked with your program. You will still need to know how to call the routines - I assume the vendor documents that.
0 Kudos
Brian_Allison
Beginner
2,595 Views
I got the list of the calls.

FUNCTION CALLS

Function CallParametersDescription
Main Function Calls
CheckLicenselong *RandomNumberMultipurpose license status evaluation
AuditLicenselong *RandomNumberGets license status without X, Y and Z valuesNOTE:Do not use this in place ofCheckLicense.
ValidateDLLlong *CustomerNumber, long *ProductNumber, long *ParmValueValidate custom dll for Customer ID, Product ID and X, Y and Z authentication constants.
InstallLicensechar *szUnlockCodeUpdates the table with new program status
InternetActivatechar *szLicenseCode, char *szpProxyPort, long PortNumberActivates license using the server
ReturnLicensechar *szLicenseCode, char *szpProxyPort, long PortNumberRemoves license and returns this to the server
RemoveLicensechar *szpRemovalCodeRemoves license from computer and returns proof of removal code.
ExportLicense
char *szLicenseCode, char *szpReturnCode
Removes license from computer and returns a deactivation certificate that can be used to manully return the license to the server

Uses, Module, Expiry Date function calls

ViewUseslong *UsesNumReturns the number of uses left in the specified counter.
SubtractUseslong *Uses, long *UsesNumSubtracts passed number from uses number.
CheckFlagslong *ModuleNumberReturns the contents of the flag table entry
ViewExpirationDatelong *Month, long *Day, long *YearReturns the expiration date
GetGeneralPurposelong *ValueGets the General Purpose Value; this is described in the manual as theCustomer Data field
PutGeneralPurposelong *Value, long *RandomNumber, long *ChecksumStores the General Purpose Value; this is described in the manual as theCustomer Data field
StartDemowchar_t *szMessage, wchar_t * szCaptionDemo Minutes Start with demo end message
EndDemoNoneStop using up demo minutes.
UpdateTimeNoneUpdates to the hard drive the number of minutes left in the evaluation period.
ViewTimeNoneReturns the number of minutes left, as an integer.
StartDemoAdvancedchar *szProcessPathSame as StartDemo, except runs whatever application is pointed to by the path name passed as a parameter.

ID function calls

GetComputerIDchar *szpComputerIDReturns unique 20-character ID for computer
DisplayInstallationIDchar *szCodeInfoReturns 12- or 32-character transaction ID

Miscellaneous function calls

DisplayVersionNoneDisplays Nalpeiron copyright notice and version number
ReturnVersionNoneReturns the version number as a 3 digit number i.e. 5.0.4 returns 504
EnterAuthenticationInformation
const char *szpProxyUsername, const char *szpProxyPassword
Enables basic http proxy authentication for functions that contact the server(version 5.9.3 or later)
GetActivationMethod
None
Returns the method that was used to activate the product(version 5.9.3 or later)
WaitForFinish
None
Suspends the thread until all threads spawned by the DLL have terminated(version 5.9.3 or later)
ReturnServiceVersion
None

It returns a 3 digit number representing the service version. For example, service version 6.5.8 is returned as 658.Only available for Windows x86/x64 filechk DLLs with a version number of 6.5.8+.

License Transfer to Media function calls

InitializeMediachar *szDriveLetterUsed by move license
RemoveToMediachar *szDriveLetterUsed by move license
InstallFromMediachar *szDriveLetterUsed by move license

Service function calls

StartTheService
None
Starts the service(version 6)
StopTheService
None
Stops the service(version 6)
0 Kudos
Steven_L_Intel1
Employee
2,595 Views
Because of the mixed-case names, you'll need to either use !DEC$ ATTRIBUTES ALIAS, or preferably, interfaces with BIND(C) to declare these. The C interoperability features will help.

This is how you'd start out:

[fortran]module LicenseCheckMod
use, intrinsic :: iso_c_binding
implicit none

interface
function CheckLicense (RandomNumber) BIND(C,NAME="CheckLicense")
import
integer(C_LONG) :: CheckLicense
integer(C_LONG) :: RandomNumber
end function CheckLicense

...
end interface[/fortran]
You would have to pay attention to those functions that accept arguments by value, such as PortNumber in ReturnLicense, and add the VALUE attribute. Character string arguments should be declared as CHARACTER, DIMENSION(*).
0 Kudos
Brian_A_
Novice
2,595 Views
I using a 64bit version of the licensing dll now and when I use the makilib file this is the message that I get:

d:\iss_relap\rs35\rs35dg64.intl\lib>MAKILIB filechck.dll
Processing: d:\iss_relap\rs35\rs35dg64.intl\lib\filechck.dll
?No .rdata section in filechck.dll?
d:\iss_relap\rs35\rs35dg64.intl\lib>
0 Kudos
Steven_L_Intel1
Employee
2,595 Views
It is likely that makilib does not know how to handle a 64-bit DLL. Using dynamic loading would be my recommendation.
0 Kudos
Brian_A_
Novice
2,595 Views
How do I use dynamic loading?
I am trying to create a def file and then a lib file using the lib.exe tool.
0 Kudos
Steven_L_Intel1
Employee
2,595 Views
You use the Windows API routines LoadLibrary and GetProcAddress. This gives you the address of a routine in the DLL and you can use either the integer pointer extension or convert it from a C_FUNPTR to a Fortran procedure pointer and call it. See the DLL\DynamicLoad sample for an example of this.

The way I would handle it is, at the beginning of the program, call LoadLibrary on the DLL and then use a series of GetProcAddress calls to fill in procedure pointers in a module. Then the rest of the program can call through the procedure pointers.
0 Kudos
Brian_A_
Novice
2,595 Views
Where do I find theDLL\DynamicLoad sample?
0 Kudos
Steven_L_Intel1
Employee
2,595 Views
You will find a Samples folder in the compiler's top-level folder. For example:

C:\Program Files (x86)\Intel\Composer XE 2011 SP1\Samples

In the en_US\Fortran subfolder of this you will find DLL.zip. Unzip this to your desktop or another writable folder and you'll find DynamicLoad in there.
0 Kudos
Reply