Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Comunicados
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
Principiante
709 Visualizações
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 Respostas
Jugoslav_Dujic
Contribuidor valorado II
709 Visualizações
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
Jugoslav_Dujic
Contribuidor valorado II
709 Visualizações
P.S. You should call FreeLibrary(hDll) when you're done with it.
jwyoung
Principiante
709 Visualizações
Yes, this helps very much and will get me going in
right direction. Thanks for your help.

Joe
Responder