What is the correct way to load a dll library in P

2020-04-30 02:09发布

问题:

The following gives an error

drop function testing();
CREATE FUNCTION testing()
 RETURNS text
AS $$
import ctypes
try:
   ctypes.windll.LoadLibrary("D:\\jcc.dll")
except:
   import traceback
   plpy.error(traceback.format_exc())
return ''
$$ LANGUAGE plpythonu;
select testing();

Error message:

ERROR:  ('Traceback (most recent call last):\n  File "<string>", line 5, in __plpython_procedure_testing_1517640\n  File "D:\\Python26\\Lib\\ctypes\\__init__.py", line 431, in LoadLibrary\n    return self._dlltype(name)\n  File "D:\\Python26\\Lib\\ctypes\\__init__.py", line 353, in __init__\n    self._handle = _dlopen(self._name, mode)\nWindowsError: [Error 126] The specified module could not be found\n',)

It works fine in a python interpretor.

Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> ctypes.windll.LoadLibrary("D:\\jcc.dll")
<WinDLL 'D:\jcc.dll', handle 410000 at 1d9cb10>
>>>

回答1:

"The specified module could not be found" is one of those helpful error messages Windows emits that doesn't always mean what you think it means.

Windows will produce that message if the DLL you tried to load or any dll it depends on could not be found.

Since PostgreSQL runs in its own user account it has a different PATH to that which your interpreter runs in when you're testing. If jcc.dll depends on (say) c:\jccsupportfiles\aaa.dll and c:\jccsupportfiles is on your PATH but not the Pg server's PATH, that would explain your problem.

Try using Dependency Walker (depends.exe) to determine which DLLs your DLL requires and where they are. See if it's a PATH issue.

Rather than messing with the Pg server's PATH, consider just putting all the DLLs required by jcc.dll in the same directory as jcc.dll. IIRC Windows will always look in the same directory as the module it's loading first when it tries to load a module it depends on.