从进程加载的 DLL 调用另一个进程中的方法
Calling a method in another process from DLL which is loaded by a process
要求:
当“屏幕键盘”中有按键时,应调用客户端应用程序中的方法
为了完成上述要求,我们正在创建一个 DLL 并导出一个回调方法。
extern "C"
{
void __declspec(dllexport) __stdcall onKeyPress(void);
}
此DLL将由“屏幕键盘”动态加载,并将调用从DLL导出的回调方法。
Where I am stuck:
我必须从 DLL 中的这个导出的回调函数调用“客户端应用程序”中的一个方法,这样每当键盘上有按键时,“客户端应用程序”就会收到通知。
我无法调用客户端应用程序中的方法。
认为屏幕键盘将加载 DLL 并将调用导出的方法,如图所示
[示例代码]
#pragma comment(lib,"..\Debug\SharedDll.lib")
__declspec(dllimport) void __stdcall calledByOnKeyPress(int scanCode);
int main(void)
{
char ch = getchar();
calledByOnKeyPress(ch);
return 0;
}
从 DLL 中,我试图在应用程序中调用类似这样的方法。
void __declspec(dllexport) __stdcall calledByOnKeyPress(int scanCode)
{
callBackFunction(scanCode);
}
我不知道如何继续...
我假设,客户端应用程序加载 dll,并且 dll 应调用应用程序中的函数。
因此您的应用程序必须注册一个函数,该函数应由 dll 调用。
因此你需要类似(简化)的东西:
void registerCallback(CallbackFunctionPointer callbackfunction){
//the app, or anyone else can call this to register a function which should be called
remember = callbackfunction;
}
并且,如果按键被按下,您调用:
void something(char ch){
//call the previously registered callback
remember(ch);
}
变量"remember"应该定义为static var,并且必须声明,如:
typedef void (*CallbackFunctionPointer) (char ch);
static CallbackFunctionPointer remember;
希望,这有帮助
当您加载一个 .dll 时,它将在不同的进程上有不同的实例(可以这么说)。
例如,如果 App1 使用 myDll.dll 并且 App2 也使用 myDll.dll,如果您从 App1 在 myDll.dll 内部进行调用,App2 将无法看到它。
Dll 只是运行时编译代码的提供者。
对于进程内通信,您需要使用进程内方法,例如通过套接字、共享内存等进行通信。
在你的情况下,根据我的理解,键盘在不同的进程中,你需要通过套接字(例如)向客户端应用程序发送键盘更改信号。
一种可能的解决方案涉及以下内容。
- SharedDll 应该定义一个可以在多个进程之间共享的公共数据段。
- 在客户端应用程序中创建一个单独的(消息)线程来接收键盘消息。然后通过导出函数的方式将这个线程的Thread ID设置到SharedDll的公共数据段。
您的屏幕键盘进程加载 SharedDll 并照常调用 onKeyPress() 函数。
在 SharedDll 的 onKeyPress() 函数中,它应该检查存储在公共 dll 数据段中的有效线程 ID。如果有一个有效的线程 ID,那么只需 post 一条线程消息。
上面的第 4 步会将您的键盘消息从 "On Screen Keyboard" 进程传递到第二个进程 "Client Application"!
中的线程 运行
Dll 公共数据段的使用是这里的决定性技术。
客户端应用程序内部
DWORD WINAPI KeyboardMsgThread( LPVOID lpParam )
{
// Start the message thread
MSG stMsg;
while( GetMessage( &stMsg, 0, KEYBOARD_MSG_MIN, KEYBOARD_MSG_MAX ))
{
// Process the keyboard message here!
}
return TRUE;
}
bool CreateKeyboardMsgThread()
{
DWORD dwThreadID = 0;
CreateThread( 0, 0, KeyboardMsgThread, 0, 0, &dwThreadID );
Sleep( 100 );// Let the message queue be created.
SetKeyboardThread( dwThreadID );//Set the thread id to the common data area.
return true;
}
SharedDll 内部
#pragma data_seg(".SHARED")
DWORD Dll_dwThreadID = 0;
#pragma data_seg()
#pragma comment(linker, "/section:.SHARED,RWS")
extern "C"
{
void __declspec(dllexport) __stdcall onKeyPress(void)
{
if( 0 != Dll_dwThreadID )
{
//When there is a valid thread id, simply post it to the thread.
//This thread can be inside any other process.
PostThreadMessage( Dll_dwThreadID, KEYBOARD_MSG_MIN, 0, 0 );
}
}
// Client Application will create the thread and calls this function to
// set the thread-id to the common-data segment so that it can be
// utilized by the instance of SharedDll which resides in the process
// space of On Screen Keyboard.
void __declspec(dllexport) __stdcall SetKeyboardThread(DWORD dwThreadID)
{
Dll_dwThreadID = dwThreadID;
}
}
屏幕键盘应用程序内部
bool RecieveKeyboardNotification()
{
onKeyPress();
}
希望对您有所帮助!
要求: 当“屏幕键盘”中有按键时,应调用客户端应用程序中的方法
为了完成上述要求,我们正在创建一个 DLL 并导出一个回调方法。
extern "C"
{
void __declspec(dllexport) __stdcall onKeyPress(void);
}
此DLL将由“屏幕键盘”动态加载,并将调用从DLL导出的回调方法。
Where I am stuck:
我必须从 DLL 中的这个导出的回调函数调用“客户端应用程序”中的一个方法,这样每当键盘上有按键时,“客户端应用程序”就会收到通知。
我无法调用客户端应用程序中的方法。
认为屏幕键盘将加载 DLL 并将调用导出的方法,如图所示 [示例代码]
#pragma comment(lib,"..\Debug\SharedDll.lib")
__declspec(dllimport) void __stdcall calledByOnKeyPress(int scanCode);
int main(void)
{
char ch = getchar();
calledByOnKeyPress(ch);
return 0;
}
从 DLL 中,我试图在应用程序中调用类似这样的方法。
void __declspec(dllexport) __stdcall calledByOnKeyPress(int scanCode)
{
callBackFunction(scanCode);
}
我不知道如何继续...
我假设,客户端应用程序加载 dll,并且 dll 应调用应用程序中的函数。
因此您的应用程序必须注册一个函数,该函数应由 dll 调用。 因此你需要类似(简化)的东西:
void registerCallback(CallbackFunctionPointer callbackfunction){
//the app, or anyone else can call this to register a function which should be called
remember = callbackfunction;
}
并且,如果按键被按下,您调用:
void something(char ch){
//call the previously registered callback
remember(ch);
}
变量"remember"应该定义为static var,并且必须声明,如:
typedef void (*CallbackFunctionPointer) (char ch);
static CallbackFunctionPointer remember;
希望,这有帮助
当您加载一个 .dll 时,它将在不同的进程上有不同的实例(可以这么说)。
例如,如果 App1 使用 myDll.dll 并且 App2 也使用 myDll.dll,如果您从 App1 在 myDll.dll 内部进行调用,App2 将无法看到它。
Dll 只是运行时编译代码的提供者。
对于进程内通信,您需要使用进程内方法,例如通过套接字、共享内存等进行通信。
在你的情况下,根据我的理解,键盘在不同的进程中,你需要通过套接字(例如)向客户端应用程序发送键盘更改信号。
一种可能的解决方案涉及以下内容。
- SharedDll 应该定义一个可以在多个进程之间共享的公共数据段。
- 在客户端应用程序中创建一个单独的(消息)线程来接收键盘消息。然后通过导出函数的方式将这个线程的Thread ID设置到SharedDll的公共数据段。
您的屏幕键盘进程加载 SharedDll 并照常调用 onKeyPress() 函数。
在 SharedDll 的 onKeyPress() 函数中,它应该检查存储在公共 dll 数据段中的有效线程 ID。如果有一个有效的线程 ID,那么只需 post 一条线程消息。
上面的第 4 步会将您的键盘消息从 "On Screen Keyboard" 进程传递到第二个进程 "Client Application"!
中的线程 运行Dll 公共数据段的使用是这里的决定性技术。
客户端应用程序内部
DWORD WINAPI KeyboardMsgThread( LPVOID lpParam )
{
// Start the message thread
MSG stMsg;
while( GetMessage( &stMsg, 0, KEYBOARD_MSG_MIN, KEYBOARD_MSG_MAX ))
{
// Process the keyboard message here!
}
return TRUE;
}
bool CreateKeyboardMsgThread()
{
DWORD dwThreadID = 0;
CreateThread( 0, 0, KeyboardMsgThread, 0, 0, &dwThreadID );
Sleep( 100 );// Let the message queue be created.
SetKeyboardThread( dwThreadID );//Set the thread id to the common data area.
return true;
}
SharedDll 内部
#pragma data_seg(".SHARED")
DWORD Dll_dwThreadID = 0;
#pragma data_seg()
#pragma comment(linker, "/section:.SHARED,RWS")
extern "C"
{
void __declspec(dllexport) __stdcall onKeyPress(void)
{
if( 0 != Dll_dwThreadID )
{
//When there is a valid thread id, simply post it to the thread.
//This thread can be inside any other process.
PostThreadMessage( Dll_dwThreadID, KEYBOARD_MSG_MIN, 0, 0 );
}
}
// Client Application will create the thread and calls this function to
// set the thread-id to the common-data segment so that it can be
// utilized by the instance of SharedDll which resides in the process
// space of On Screen Keyboard.
void __declspec(dllexport) __stdcall SetKeyboardThread(DWORD dwThreadID)
{
Dll_dwThreadID = dwThreadID;
}
}
屏幕键盘应用程序内部
bool RecieveKeyboardNotification()
{
onKeyPress();
}
希望对您有所帮助!