【问题标题】:letting a DLL call a exe function with function pointer让 DLL 调用带有函数指针的 exe 函数
【发布时间】:2013-03-08 23:20:53
【问题描述】:

谁能告诉我我做错了什么? 我正在尝试在不同的线程上运行自定义主线程。

这是代码。

.exe
main.cpp

#include "dll_class.h"
#include <iostream>
int main(void);
DllClass object(main);
int main(void)
{
    std::cout << "Enter the main code.\n";
    std::getchar();
}

.dll
dll_class.h

#include "platform.h"
#include <iostream>
class DLL_API DllClass //DLL_API is just a macro for import and export.
{
public:
    DllClass(int(*main)(void))
    {
        std::cout << "Start application.\n";
        platform = new Platform(main);
    }
    ~DllClass(void)
    {
        delete platform;
    }
private:
    Platform* platform;
};

平台.h

class DLL_API Platform
{
public:
    Platform(main_t main_tp);
    ~Platform(void){}
};

平台.cpp

#include "platform.h"
#include "Windows.h"
#include <iostream>

HHOOK hookHandle;
int(*main_p)(void);//This will hold a the main function of the the .exe.
LRESULT CALLBACK keyHandler(int nCode, WPARAM wParam, LPARAM lParam);

DWORD WINAPI callMain(_In_  LPVOID lpParameter)
{
    std::cout << "Calling the main function.\n";
    main_p();
    return 0;
}

Platform::Platform(int(*main_tp)(void))
{
    main_p = main_tp;
    CreateThread(NULL, 0, callMain, NULL, 0, NULL);
    std::cout << "Setting hooks.\n";
    hookHandle = SetWindowsHookEx(WH_MOUSE_LL, keyHandler, NULL, 0);
    std::cout << "Enter message loop.\n";
    MSG message;
    while(GetMessage(&message, (HWND)-1, 0, 0) != 0){
        TranslateMessage( &message );
        DispatchMessage( &message );
    }
}

LRESULT CALLBACK keyHandler(int nCode, WPARAM wParam, LPARAM lParam)
{
    std::cout << "Inside the hook function.\n" << std::endl;
    return CallNextHookEx(hookHandle, nCode, wParam, lParam);
}

它运行得很好,直到某个时刻。 这是输出。

Start application.  
Setting hooks.  
Calling the main function.  
Enter message loop.  
Inside the hook function. (A lot of times of course).  

但它从来没有说:

Enter the main code.

难道不能让dll调用exe函数吗?

【问题讨论】:

  • 您的平台构造函数尚未返回。 main 在构造对象之前无法运行,并且您的构造函数尚未完成。

标签: c++ multithreading winapi


【解决方案1】:

从共享库调用可执行文件中的函数是非常可能的。但是,正如另一个答案中提到的,C 标准不允许您致电main。这与以下事实有关在main 之前,您会遇到问题。

如果您的目标是真正颠覆 main 所做的事情,那么您将不得不找到一种不同的方法来实现这一目标 - 至少如果您希望它适用于多个特定的可执行文件。

【讨论】:

  • 我认为这是一个完全不同的问题 - 我不完全确定我 a) 完全理解这个问题或 b) 知道它的答案。显然,在生成 .NET 之类的东西时,这是一个相当复杂的过程,我不能说我实际上知道它的作用...... .NET“启动过程”很可能是其他东西的包装 - 但这是一个猜测,而不是知识。
  • 对不起,我的问题没有完成。他以某种方式发布了它。
  • 谢谢,我正在尝试围绕 WinAPI 和 .NET 创建一个层。我注意到当 .NET 应用程序的主要部分返回时,它会在较低级别中走得更远。 main 本身就是一个线程,不是吗?我试图创造同样的效果。我想确保在用户调用 main 之前设置了钩子并且消息循环正在运行。有没有替代方案。如果我创建像 my_main 这样的自定义 main,我可以确保他们不必同时调用 main 和 my_main
  • 在 C 或 C++ 程序中,如果您想使用 C/C++ 运行时库提供的任何服务,您必须调用 main [当然,可能有一些函数不需要它,但如果你这样做,你将处于“未定义的行为领域”]。如果您正在为不同的语言构建自己的运行时,并且不使用正常的 C 运行时功能 [我希望 .NET 会这样做],那么这没什么大不了的。但是,如果您希望常规的 C 或 C++ 代码能够正常工作,那就别管它了。
【解决方案2】:

C++ 标准不允许调用 main() 或获取其地址,这就是您在这里所做的。请参阅引用行和诗句的this 线程。所以,你在做什么是未定义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    相关资源
    最近更新 更多