DLL problem

  • Thread starter PaulHollingshead via AccessMonster.com
  • Start date
P

PaulHollingshead via AccessMonster.com

I'm an experienced coder and have worked with many DLLs in the past but this
one has me beat.

I'm creating a software link between our dental system (Access97 & 2000 - yep
we cater for people with very old hardware) and a french digital xray system
(Kodak).

They have provided a number of function calls (only providing C++ sample
calling code) that operate on a single Historique.DLL. They also provided a
stand alone EXE that demonstrates the function calls. I also managed to get
an old demo CD of there software and installed it on my Access 97 Windows
2000 virtual machine I use for development. Note: There software insisted on
Win2000 SP3 being installed (and there installer also put XML 4 on it).

When I try a VBA call to one of these functions I get "error 53 file not
found". The DLL does exist but the error message explicitly says the file
(with whole path/filename in error message) doesn't exist. I tracted this
down via MSDN article 178489 as a problem with a dependancy.

The EXE sample app they provided also reported the Historique DLL couldn't be
found.

Using dependancy walker (watching there sample EXE app) I located some
"missing" DLLs that this main Historique DLL uses. I then found they existed
in the same directory as the Historique DLL. REGSVR32 has no affect on any of
these DLLs - it can't find any start points. The DLLs are barely mentioned in
the registry at all. Putting copies of the DLLs into the windows system32
folder also doesn't fix the problem.

Putting the sample EXE into the same directory as the Historique DLL actually
fixes it. That sample app now works. Putting our development mdb in the same
place has no affect.

Any ideas?

Paul
 
A

Albert D. Kallal

Putting the sample EXE into the same directory as the Historique DLL
actually
fixes it. That sample app now works. Putting our development mdb in the
same
place has no affect.

Any ideas?

Paul
\

Obviously that .exe program was designed to look for, and load the DLL
library code.

By default, or by its nature MS access applications do not find, or
automatic use dll's simply because they're placed in the same directory.

You could however try placing the dll in the same directory as a
MSaccess.exe file, or the windows system 32 directory. If you don't wanna
write any additional code, or just get this working without hassles, then
ignore the follwoing, and try my suggestions above.


I have two suggestions....

1) you must get the dll's registered (that means you MUST use regsvr32 to
"register" the dll's. If you don't do this then when you use the public
declare functions in MS access to use this DLL, access will simply not know
where to look to find the file.

I would check with the manufacture, or least try to find some documentation
somewhere as to how to correctly register these required dll's. It's
possible that you have to use the original installer with the original
software to install the dll files. Unless you register these files, your
API and declare functions in access will not find the dll.

I assume that your declares to use these DLL's looks something like

-- This Assumes UNZIP32.DLL Is In Your \Windows\System Directory!
Private Declare Function Wiz_SingleEntryUnzip Lib "unzip32.dll" _
(ByVal ifnc As Long, ByRef ifnv As UNZIPnames, _
ByVal xfnc As Long, ByRef xfnv As UNZIPnames, _
dcll As DCLIST, Userf As USERFUNCTION) As Long

If you note in the above, you can see how it is assumed that the DLL is in
your what windows system directory. I would suggest you also will attempt
doing the above, and your declares might work without further effort.

The second solution, and it is the one that I use all the time, and is also
the solution that a highly recommend, is to simply use the windows API to
load the dll file you need. What this means that if you can place the DLL in
the same directory as your access application, and have your code load the
dll.

The advantage of the above approach is quite obvious, as you don't have to
register the file, you don't have to place in the system directory, and
furthermore no matter which machine you copy the folder with your
application to, it will continue to function.

If you're looking for sample code as to how this is done you can grab my
example code here:

I have a zipping routine here:

http://www.members.shaw.ca/AlbertKallal/zip/index.htm

The above is a win zip utility, that uses two external dll's for the zipping
of the files, but I call that the DLL from MS access. Another example of an
access application that uses external dll's and this loading of the files is
Stephen's pdf creater. His sample code can be found here:

http://www.lebans.com/reporttopdf.htm

The API to declare to load DLL's is as follows

Private Declare Function LoadLibrary Lib "kernel32" _
Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long

and, to un-load (you likey don't need this)

Private Declare Function FreeLibrary Lib "kernel32" _
(ByVal hLibModule As Long) As Long

In your code you'll simply declare your API functions as normally


right before you call your code, you go:

dim hLibZip = LoadLibrary(strDll)

strDll has the path ame to the dll. file...

eg:

strDll = CurrentProject.path & "\zip32.dll"

(note a97 does not have currentProject.path)...you have to use:

'******************** Code Begin ****************
'Code courtesy of
'Terry Kreft & Ken Getz
'
Private Function CurrentDBDir() As String
Dim strDBPath As String
Dim strDBFile As String
strDBPath = CurrentDb.Name
strDBFile = Dir(strDBPath)
CurrentDBDir = Left$(strDBPath, Len(strDBPath) - Len(strDBFile))
End Function
'******************** Code End ****************


I have to admit, I have no idea if the above will work for you. I am very
much assuming that if you can't register those dll files, or they don't
work when you place them in the same dir as msaccess.exe (or windows system
32), then I can't see how the above would legitimize this and allow you to
load them.

Regardless, I been deploying software to many people all over in different
locations and even different countries, and I've never had a problem in
terms of a non registered dll's by loading them in code. I also suspect
this is what makes Stephens pdf creator code also very reliable.

Another bonus of the above reproach of course is that when you install your
software to a new machine, you simply drag the folder into a directory, and
you don't have to write some install script to register those dll files.
 
A

Albert D. Kallal

I should also point out here, that regsvr32 is only needed for activex (com)
libary cde. What I said in the previous is thus a little bit confusing, or
is somewhat incorrect on my part.

ActiveX, or so called "com" objects need to be registered.

However, a good portion of dll files are not necessarily com objects, but
simply external libary code that needs to be called by your code. Note that
these cases you don't use tools->references in ms-access to set up a
refercnce to this type of code.

So in your case, it sounds like this is not com object, but simply some
external library code.

So either place the dll in the windows system 32 directory, or use the load
api example I gave. Also, you might get it to work if you place in the same
directory as msaccess.exe.

However my information about you not being able to use regsvr32 is not quite
right if this is not a com object. My spiders sense tells me that this is
your case.

I should also stress at this point in time, that this load API example does
NOT work for com (activeX) objects.

So you'll need to determine if you dealing with a com object or not. Ssince
the other .exe seem to run the deal dll code just fine, then I'm guessing
this is a standard library (dll) piece of code.
 
P

PaulHollingshead via AccessMonster.com

I tried a trial and error method.

I made a fresh new directory and put the sample EXE in there. Then, using
dependency walker as a guide, I added DLLs that were requested.

In the end the Historique.DLL wanted another 36 DLLs to allow it to work.
Putting all 37 in SYSTEM32 seems to get my VBA DLL calls to work.

REGSVR32 won't touch them. LOADLIBRARY api call does return a handle.

Dependancy walker reports that Historique.DLL was written in C / C++.

Now I'm going to explore what I can do with these DLL calls.

Paul
 
T

Tony Toews [MVP]

PaulHollingshead via AccessMonster.com said:
In the end the Historique.DLL wanted another 36 DLLs to allow it to work.
Putting all 37 in SYSTEM32 seems to get my VBA DLL calls to work.

What happens if you put those in the same folder as your MDB? Does
your app still work?

Tony
--
Tony Toews, Microsoft Access MVP
Please respond only in the newsgroups so that others can
read the entire thread of messages.
Microsoft Access Links, Hints, Tips & Accounting Systems at
http://www.granite.ab.ca/accsmstr.htm
Tony's Microsoft Access Blog - http://msmvps.com/blogs/access/
 
S

Stephen Lebans

Paul I simply cannot believe you have to copy 36 DLL's into a folder to call
the functions exported by the Historique.DLL. Post your code for the
Historique library function signatures.

Finally, are you sure the Historique library was compiled to allow being
called from Visual Basic?

--

HTH
Stephen Lebans
http://www.lebans.com
Access Code, Tips and Tricks
Please respond only to the newsgroups so everyone can benefit.
 
P

PaulHollingshead via AccessMonster.com

Tony said:
What happens if you put those in the same folder as your MDB? Does
your app still work?

Tony

No, that doesn't work.

Paul
 
P

PaulHollingshead via AccessMonster.com

Stephen said:
Paul I simply cannot believe you have to copy 36 DLL's into a folder to call
the functions exported by the Historique.DLL. Post your code for the
Historique library function signatures.

Finally, are you sure the Historique library was compiled to allow being
called from Visual Basic?


The PDF document outlining this software link only talks about C / C++.
Looking at it now it does list all 37 DLLs in a "software development kit
packing list". Clearly never intended for VB use.

Some functions do pass back data structures that I cannot reproduce in VBA. I
don't mind this because the main aim of my code is to activate there software
from my system. I'm not interested in filenames of xrays being passed back so
I can "On error" around them to catch those situations. The error only occurs
when a user attempts to "select" an xray - it doesn't occur when the xray
software is initially activated by the DLL call.

The chap I've been talking to at the xray software company has now returned
off holiday so I hope he'll get around to returning my emails.

Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top