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 on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

DLL Problem

jwyoung
Beginner
704 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
704 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
704 Views
P.S. You should call FreeLibrary(hDll) when you're done with it.
0 Kudos
jwyoung
Beginner
704 Views
Yes, this helps very much and will get me going in
right direction. Thanks for your help.

Joe
0 Kudos
Reply