Подсказываю.
Способ 1. Не выходя на замки Declare.Перед самым первым (хронологически) вызовом функции из DLL: установить её путь в качестве текущего (с помощью ChDir, ChDrive) вызвать функцию, после чего вернуть оригиналное значение CurDir. В дальнейшем можно вызывать функции как обычно.
Т.е., скажем, библиотека называется TestDll, а путь к ней лежит в переменной TestPath:
Загвоздка в том, что надо помнить о текущих папках, о том, что у каждого тома она своя.
- Код: Выделить всё
Declare Sub SomeDummyFunctionFromTestDll Lib "TestDll.dll" ()
...
Public Sub LoadMyDll()
Dim sCurDir As String
Dim sCurDrive As String
sCurDrive = Left$(CurDrive, 2)
ChDrive Left$(TestPath, 2)
sCurDir = CurDir
ChDir TestPath
SomeDummyFunctionFromTestDll ' Один этот вызов заставит библиотеку загрузиться
ChDir sCurDir
ChDrive sCurDrive
End Sub
После этого остальные функции можно вызывать без всякой мороки. Также в этом коде стоило бы сделать проверку на ошибки 53 (File not found) и 453 (Can't find entry point ...).
Способ 2. Не выходя за рамки Declare, но выходя за рамки VB.Его можно использовать, если не только путь, но и имя файла библиотеки заранее неизвестно. Или если не нравятся манипуляции с текущей папкой.
Суть заключается в следующем:
Вместо имени файла DLL указывается некая метка, заведомо не являющаяся путем. Лучше чтобы она была уникальной. Для этого можно например использовать UUID, но я буду использовать {MyCoolDllFileName}.
- Код: Выделить всё
Declare Function SomeA Lib "{MyCoolDllFileName}" (...) As ...
Declare Function SomeAbc Lib "{MyCoolDllFileName}" (...) As ...
Declare Function SomeDef Lib "{MyCoolDllFileName}" (...) As ...
Declare Function SomeEgEg995 Lib "{MyCoolDllFileName}" (...) As ...
Declare Function StartBaCaDa Lib "{MyCoolDllFileName}" (...) As ...
При этом, в самом начале (до самого первого вызова из библиотеки) нужно перехватить функцию kernel32!LoadLibraryA. При перехвати, нужно сравнить переданный пусть с "{MyCoolDllFileName}", и если переданный пусть совпал с "{MyCoolDllFileName}", то заменить его на треюуемый путь. При этом код перехвата может (и даже должен) снять перехват, поскольку больше он не требуется.
Можно таким же образом перехватывать msvbvm60!DllFunctionCall, но во-первых тебе будет сложнее, а во-вторых, работало бы только в скомпилированном варианте.
Способ 3. Выходя за рамки DeclareПросто вызывать по указателю с помощью LoadLibrary+GetProcAddress