Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs have moved to the Altera Community. Existing Intel Community members can sign in with their current credentials.

DLL Problem

jwyoung
Beginner
728 Views
I am in the process of converting a program from
Liberty Basic to Visual Fortran and have succeeded
to the point that only one unresolved problem remains.
The chances of "guessing" my way through this one are
slim.

I am using a DLL to access a database on a CDROM and
pass the returned data array to the Liberty Basic program.
The Liberty Basic code follows:

dim return$(25) '25 fields
open "raccd32a.dll" for dll as #dll
struct errorcd, error as short
value$ = wlcallsign$ 'search key
print GetCall(value$) 'invoke function
close #dll

function GetCall(value$)
cddrive$ = "D: + chr$(0) 'zero terminated
AcallID$ = value$ + chr$(0) 'key
info$ = space$(500) + chr$(0) 'returned data
calldll #dll, "cGetCallInfo",_ 'call DLL
cddrive$ as ptr,_
AcallID$ as ptr,_
info$ as ptr,_
errorcd as struct,_ ' 0 for success
r as long
for i = 1 to 25 'data array(25)
s = instr(info$,chr$(i))
if s>0 then
e = instr(info$,chr$(i+1))
if e = 0 then e = len(info$) + 1
return$(i) = mid$(info$,s+1,e-s-1) 'returned data
end if
next i
end function

cddrive$, AcallID$ and info$ are pointers to zero-terminated strings. These strings have to exist at the moment of calling cGetCallInfo. The calling
program is responsible for creating them. info$ must be long enough to hold cGetCallInfo (at least 400 characters).

In errorcd , cGetCallInfo returns information about the success of the search. For a successful search (AcallID$ having been found) it is zero. All other values indicate an error.

The above code functions as it should; but I would like to be able to do the same thing in VF. Thank you.

Joe Young
0 Kudos
3 Replies
Jugoslav_Dujic
Valued Contributor II
728 Views
I'll skip string operations, which you probably know how to handle (look at TRIM, INDEX, CHAR(0), // operator, REPEAT). You're probably interested in how to handle the call to dll -- you'll need a pointer to function and few API calls. Here you are (parts you may need to adjust are bolded):
use dfwin
interface
   subroutine cGetCallInfo(cddrive$, acallid$, info$, errorcd)
   !dec$attributes stdcall, reference:: cGetCallInfo
   character(*):: cddrive$, acallid$, info$
   integer(2):: errorcd !I don't know what's struct in LB
   end subroutine
end interface
pointer(pGetCallInfo, cGetCallInfo)
!
hDll = LoadLibrary("raccd32a.dll"//char(0))
if (hDll == 0) stop "Dll not found" !i.e. error handling
pGetCallInfo = GetProcAddress(hDll, "cGetCallInfo"//char(0))
!use "Dependency walker" or dumpbin /exports raccd32a.dll
!to retrieve real exported name. Case matters.
if (pGetCallInfo == 0) stop "Routine not found" 
call cGetCallInfo(cddrive$, AcallID$, info$, errorcd)
if (errorcd == 0) then
  ...
Hope this helps,
Jugoslav
0 Kudos
Jugoslav_Dujic
Valued Contributor II
728 Views
P.S. You should call FreeLibrary(hDll) when you're done with it.
0 Kudos
jwyoung
Beginner
728 Views
Yes, this helps very much and will get me going in
right direction. Thanks for your help.

Joe
0 Kudos
Reply