刚接手一个VB程序,以前没用过VB,结果碰到好多问题啊。。都快疯了。我的需求:
调用exe所在文件夹下的一个dll文件dll的接口函数:
extern "C" __declspec(dllexport) int LOGON_LogOn(void);我的方法:
VB6不能使用相对路径来调用
so我用了LoadLibrary代码如下:
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Any, ByVal wParam As Any, ByVal lParam As Any) As LongPrivate Sub Form_Load()
On Error Resume Next
Dim lb As Long, pa As Long
Lb = LoadLibrary("LogOn.dll")
pa = GetProcAddress(lb, "LOGON_LogOn")
CallWindowProc GetProcAddress(lb, "LOGON_LogOn"), Me.hWnd, 0, 0, 0
FreeLibrary lb
End Sub结果CallWindowProc GetProcAddress(lb, "LOGON_LogOn"), Me.hWnd, 0, 0, 0出错
查了一下,发现CallWindowProc只能引用:有四个入参的函数....那请问大侠,我想要调用任意个数的DLL接口函数,该如何实现?或者更直接一点,如何才能让我使用相对路径来调用DLL?
调用exe所在文件夹下的一个dll文件dll的接口函数:
extern "C" __declspec(dllexport) int LOGON_LogOn(void);我的方法:
VB6不能使用相对路径来调用
so我用了LoadLibrary代码如下:
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Any, ByVal wParam As Any, ByVal lParam As Any) As LongPrivate Sub Form_Load()
On Error Resume Next
Dim lb As Long, pa As Long
Lb = LoadLibrary("LogOn.dll")
pa = GetProcAddress(lb, "LOGON_LogOn")
CallWindowProc GetProcAddress(lb, "LOGON_LogOn"), Me.hWnd, 0, 0, 0
FreeLibrary lb
End Sub结果CallWindowProc GetProcAddress(lb, "LOGON_LogOn"), Me.hWnd, 0, 0, 0出错
查了一下,发现CallWindowProc只能引用:有四个入参的函数....那请问大侠,我想要调用任意个数的DLL接口函数,该如何实现?或者更直接一点,如何才能让我使用相对路径来调用DLL?
你把LogOn.dll放在c:\windows\system32文件夹下(Win64位系统放在c:\windows\syswow64文件夹下)
Private Declare Function LOGON_LogOn Lib "LogOn" () As Long
* 可执行文件(程序)所在的路径,可能就是你所说的 exe 所在路径;
* Windows 所在路径
* Windows\System32 路径所以,你直接如 1 楼声明即可调用。“VB6不能使用相对路径来调用”是听谁说的?
我就是不想使用这个,我想把dll和配置文件,exe等放在一个文件夹下,这样在其他机器上使用时直接拷贝过去就可以了。
如果直接显式调用,Private Declare Function
我怎么还会这么烦呢。。
确实不行啊,或者你给我段代码参考一下?
Private Declare Function LOGON_LogOn Lib "LogOn" () As Long
Private Declare Function LOGON_LogOn Lib ".\LogOn" () As Long
Private Declare Function LOGON_LogOn Lib "\LogOn" () As Long
都不行,
必须是绝对路径
该示例演示如何在标准模块的模块级使用 Declare 语句来声明对动态链接库 (DLL) 中的一个外部过程的引用。如果是 Private 的 Declare 语句,则可以用于类模块。'在 Microsoft Windows(16 位)中:
Declare Sub MessageBeep Lib "User" (ByVal N As Integer)
'假设 SomeBeep 是该过程名的别名。
Declare Sub MessageBeep Lib "User" Alias "SomeBeep"(ByVal N As Integer)
'在 Alias 子句使用顺序号来调用 GetWinFlags。
Declare Function GetWinFlags Lib "Kernel" Alias "#132"() As Long'在 32 位 Microsoft Windows 系统中,指定的库应是 USER32.DLL,
'而不是 USER.DLL。可以使用条件编译来编写
'既可在 Win32 又可在 Win16 环境运行的代码。
#If Win32 Then
Declare Sub MessageBeep Lib "User32" (ByVal N As Long)
#Else
Declare Sub MessageBeep Lib "User" (ByVal N As Integer)
#End If
我就是不想使用这个,我想把dll和配置文件,exe等放在一个文件夹下,这样在其他机器上使用时直接拷贝过去就可以了。
如果直接显式调用,Private Declare Function
我怎么还会这么烦呢。。
用这个不会死人的!
我就是不想使用这个,我想把dll和配置文件,exe等放在一个文件夹下,这样在其他机器上使用时直接拷贝过去就可以了。
如果直接显式调用,Private Declare Function
我怎么还会这么烦呢。。
用这个不会死人的!
流行的安装程序都用这个的。
我就是不想使用这个,我想把dll和配置文件,exe等放在一个文件夹下,这样在其他机器上使用时直接拷贝过去就可以了。
如果直接显式调用,Private Declare Function
我怎么还会这么烦呢。。
用这个不会死人的!
流行的安装程序都用这个的。我已经说了,我需要的不是这个
我需要的是能使用相对路径来调用DLL。因为条件规定就是一个工具包,没有安装,在任意电脑上解压直接可用。如果用Private Declare Function可以实现,可以告诉我怎么在这条代码里面使用相对路径吗?
或者使用LoadLibrary的话,如何才能让CallWindowProc调用只有一个参数的函数?
但是这样只是换个方法实现而且,而且治标不治本。万一有的电脑有系统文件夹访问权限,这样就执行不了了。
所以我才想问一下,有什么办法能在代码中调用相对路径的DLL(DLL就放在程序exe同目录下)因为我对VB不熟悉,现在又需要拿VB来改以前别人写的一个测量程序。
The LoadLibrary function maps the specified executable module into the address space of the calling process. HINSTANCE LoadLibrary(
LPCTSTR lpLibFileName // address of filename of executable module
);
Parameters
lpLibFileName
Pointer to a null-terminated string that names the executable module (either a .DLL or .EXE file). The name specified is the filename of the module and is not related to the name stored in the library module itself, as specified by the LIBRARY keyword in the module-definition (.DEF) file.
If the string specifies a path but the file does not exist in the specified directory, the function fails. When specifying a path, be sure to use backslashes (\), not forward slashes (/). If the string does not specify a path, the function uses a standard search strategy to find the file. See the Res for more information. Return Values
If the function succeeds, the return value is a handle to the module.If the function fails, the return value is NULL. To get extended error information, call GetLastError. Res
LoadLibrary can be used to map a DLL module and return a handle that can be used in GetProcAddress to get the address of a DLL function. LoadLibrary can also be used to map other executable modules. For example, the function can specify an .EXE file to get a handle that can be used inFindResource orLoadResource. Do not use LoadLibrary to "run" a .EXE file. If the module is a DLL not already mapped for the calling process, the system calls the DLL's DllMain function with the DLL_PROCESS_ATTACH value. If the DLL's entry-point function does not return TRUE, LoadLibrary fails and returns NULL. It is not safe to call LoadLibrary from DllMain. For more information, see the Res section in DllMain. Module handles are not global or inheritable. A call to LoadLibrary by one process does not produce a handle that another process can use — for example, in calling GetProcAddress. The other process must make its own call to LoadLibrary for the module before calling GetProcAddress. If no filename extension is specified in the lpLibFileName parameter, the default library extension .DLL is appended. However, the filename string can include a trailing point character (.) to indicate that the module name has no extension. When no path is specified, the function searches for loaded modules whose base name matches the base name of the module to be loaded. If the name matches, the load succeeds. Otherwise, the function searches for the file in the following sequence: The directory from which the application loaded.
The current directory.
Windows 95 and Windows 98: The Windows system directory. Use theGetSystemDirectory function to get the path of this directory.
Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32. Windows NT: The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
The Windows directory. Use theGetWindowsDirectory function to get the path of this directory.
The directories that are listed in the PATH environment variable.
The first directory searched is the one directory containing the image file used to create the calling process (for more information, see the CreateProcess function). Doing this allows private dynamic-link library (DLL) files associated with a process to be found without adding the process's installed directory to the PATH environment variable.
The Visual C++ compiler supports a syntax that enables you to declare thread-local variables: _declspec(thread). If you use this syntax in a DLL, you will not be able to load the DLL explicitly using LoadLibrary or LoadLibraryEx. If your DLL will be loaded explicitly, you must use the thread local storage functions instead of _declspec(thread). Windows 95: If you are using LoadLibrary to load a module that contains a resource whose numeric identifier is greater than 0x7FFF, LoadLibrary fails. Windows CE: Two different modules cannot have the same filename, given that the extensions are different. These effectively have the same "module" name. For example, if LoadLibrary is made on "Sample.cpl", the operating system will not load Sample.cpl, but instead will again load Sample.dll. A similar limitation exists for modules with the same name but residing in different directories. For example, if LoadLibrary is called on "\\Windows\Sample.dll", and then LoadLibrary is called on "\\MyDir\Sample.dll", "\\Windows\Sample.dll" will simply be reloaded.A search path to the executable module cannot be specified. Unless the full path to the module is given, Windows CE will search the following path for the module: The root directory of the PC Card RAM expansion card, if one exists.
The windows directory (\Windows).
The root directory (\).
QuickInfo
Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.See Also
Dynamic-Link Libraries Overview, Dynamic-Link Library Functions, DllMain,FindResource, FreeLibrary, GetProcAddress,GetSystemDirectory,GetWindowsDirectory, LoadLibraryEx,LoadResource
看看这个行吗?
OnError Goto ErrProc:
Debug.Print 1 / 0
InDebugMode = False
Exit Function
ErrProc:
InDebugMode = True
End Function在主程序中
If InDebugMode Then
使用一个硬编码的路径
Else
使用App.Path找相对路径
End If
你说的那些“路径问题”根本就是不存在的问题。
楼主真是没事找事!
先用C封装一个 dll,接口为 stdcall 的,也放在 exe 目录下。
然后直接 Declare 声明即可调用。
不用 LoadLibrary,也不存在路径问题,一切 OK!
Function RunDll(SubFunctionName As String, ParamArray Parameters() As Variant)
RunDll (“LOGON_LogOn”,参数1,参数2,参数3,参数4)ParamArray Parameters(,这个是可以压入任意个参数的
刚升3星没多久。
最近偶尔来看看,回复一些贴子。
我用手机上的论坛,我自己都不清楚哪天升级的。
手机上进论坛后,必须要点“电脑版”,才能看到头像和等级。
要不然只看到个ID,不是特别熟悉的人,都“不认识”呢。
你好像很久没有来论坛了,现在怎么有空来呀?
你忽悠谁呢!!!
你如果通过程序指令完成注册过程,
那不代表“不需要注册”!
OCX文件如果跟.EXE放一块,
那可以说“不用注册”:
系统加载程序时,会帮你把它注册。
但COM的DLL好像跟.exe放一起也不行。更何况,你说你的“全在内存中”,
系统在哪去找它?