Awesome, thanks Zak!  It *was *using ctypes, so calling LoadLibrary
manually fixed it.

G


On Tue, Mar 26, 2013 at 11:03 AM, Zak <[email protected]> wrote:

> I had a similar problem with a ctypes DLL. I wrote a library in C, let's
> call it my_lib.dll, and it worked fine in --onedir mode. It gave this same
> error in --onefile mode (if I recall correctly). The problem was that when
> Python tried to load my_lib.dll, it was looking in the wrong folder. It was
> looking in the folder holding the --onefile EXE, it was not looking in the
> temp directory created by the PyInstaller bootloader. The example
> application below shows the solution:
>
> # pyi_ctypes_example.py
> #
> # By Zak Fallows, 2013-03-26
> #
> # Point PyInstaller at this file, this is the base script.
> #
> # PyInstaller has a problem when working with ctypes DLLs in --onefile
> mode.
> # The problem appears as the following error message:
> #   WindowsError: [Error 126] The specified module could not be found
> # At least, I think that is the error message. I am only 95% sure. The core
> # of the problem is that if you freeze the app to create my_app.exe, and
> the
> # file my_app.exe is in C:\Users\zakf\Downloads\my_**app.exe, then the app
> # will look for DLLs in C:\Users\zakf\Downloads\, it will NOT look for DLLs
> # in C:\Users\zakf\AppData\Local\**Temp\_MEI8482\, but this latter
> directory
> # (which is the PyInstaller temp directory) is where the DLL is actually
> # located. We must hack the Python so that it looks for the DLL in the temp
> # directory, rather than the directory that holds the EXE.
> #
> # Much of this file is copied from saber/pyi_utils.py
>
> from ctypes import *
> import sys
> import os.path
>
> def resource_path(relative_path):
>     """Returns the path to a resource file in the PyInstaller temp
> directory
>
>     Arguments:
>         relative_path   String, e.g. "my_lib.dll"
>
>     When this file is running in development (i.e. it has not been
> packaged by
>     PyInstaller yet), this function returns a path such as:
>         C:/Users/zakf/my_app/my_lib.**dll
>     But when this app is running in frozen mode (i.e. it has been packaged
> by
>     PyInstaller and it is now a --onefile executable), the resource files
> are
>     in a very different place. In --onefile frozen mode, the resource files
>     are all extracted to a temporary directory. The path to the temporary
>     directory is given by sys._MEIPASS. Thus, resource_path() will return
> the
>     correct path to the resource file in the temporary directory, such as:
>         C:/Users/zakf/AppData/Local/**Temp/_MEI8482/my_lib.dll
>
>     """
>
>     try:
>         temp_dir_path = sys._MEIPASS
>     except AttributeError:
>         temp_dir_path = os.path.abspath(".")
>     return os.path.join(temp_dir_path, relative_path)
>
> dll_path = resource_path("my_lib.dll")
> lib = cdll.LoadLibrary(dll_path)
>
> # Call a function in the DLL:
>
> lib.my_function(c_int(5))
>
> I am also attaching this example as a Python file. It works, all you need
> to do is add the DLL.
>
> I don't know if you are using ctypes to call the DLL. If you are using
> something else, then it may be having a similar problem. It may not be
> looking in the right directory (the temp dir) for the DLL. There are two
> possible solutions:
>
> 1. Do something like what I did. Tell it where to look.
>
> 2. When you distribute your app, tell the users that they need a copy
> avbin.dll sitting right next to the EXE. They must keep the EXE and DLL
> together, because the EXE will look for the DLL in its home folder. This is
> silly but it works. You package with --onefile, but you have to distribute
> two files.
>
> Good luck,
>
> Zak Fallows
>

-- 
You received this message because you are subscribed to the Google Groups 
"PyInstaller" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/pyinstaller?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to