调用特定DLL

时间:2015-07-23 04:37:48

标签: c++ multithreading visual-c++ dll chromium-embedded

我有一个MSVC项目,该项目由从可执行文件调用的多个DLL组成。其中一个DLL初始化CEF(Chromium Embedded Framework),另一个提供其他一般功能,我们称之为cefDLL和generalDLL。这些电话是这样的:

  1. 所有调用都是从可执行文件中完成的。
  2. 我在cefDLL中调用函数来初始化CEF。
  3. 我将函数称为第二个通用DLL。
  4. CEF内部的一些线程崩溃时出现Windows错误弹出报告“应用程序无法启动正确(0xc0000124)。单击确定关闭应用程序。”。
  5. 出现Windows弹出窗口,声明Application.exe已停止工作。
  6. 即使我在“已停止工作”弹出窗口中关闭程序,主线程仍继续运行。
  7. 如果我尝试在崩溃的程序上运行调试器,我得到一个空白的Visual Studio,没有调用堆栈,没有本地,没有,甚至没有失败的DLL的名称。

    如果我从另一个DLL调用一个函数,一个来自可执行文件本身的函数或根本没有调用函数,代码就达到我的无限循环就好了(我正在使用一个无限循环来阻止程序的其余部分运行)。

    如果我让它继续运行到程序的其余部分并且不用无限循环停止它,CEF中的另外两个线程崩溃总共三个崩溃的线程。这些产生与第一个线程完全相同的错误。我不确定是什么原因引起的,因为我还没有时间研究这个问题。

    即使在通用DLL中调用的函数完全不执行任何操作,这仍然会发生。如果我的代码是

    ,我确信这是调用它们的行为导致这种情况
    initializeCEF();
    
    while (true)
    {
    
    }
    

    如果代码是

    ,它可以工作
    initializeCEF();
    
    someBlankFunctionInGeneralDLL();
    
    while (true)
    {
    
    }
    

    线程崩溃。

    CEF的初始化包括:

    //Initialize
    CefMainArgs mainArgs;
    
    //Launch Threads
    CefExecuteProcess(mainArgs, nullptr, nullptr);
    
    //Settings
    CefSettings settings;
    settings.pack_loading_disabled = true;
    settings.windowless_rendering_enabled = true;
    settings.multi_threaded_message_loop = false;
    settings.no_sandbox = true;
    
    //Sandbox Info
    void *sandboxInfo = nullptr;
    
    //Launch System
    CefInitialize(mainArgs, settings, nullptr, sandboxInfo);
    

    有没有人最清楚这可能是由什么造成的?它很容易成为我遇到过的最奇怪的错误之一。 这个项目是5万左右的巨型项目,并没有任何其他相关部分,所以我不能真正提供任何我担心的例子。如果有一些代码你认为它会有所帮助,请告诉我。

1 个答案:

答案 0 :(得分:1)

你知道CEF是多进程的,对吧?初始化CEF的主应用程序是否可能无法正确启动多个实例,或者在启动时未将所需的命令行参数传递给包含CEF的DLL?请参阅此文档,了解CEF应用程序的结构:https://bitbucket.org/chromiumembedded/cef/wiki/Architecture#markdown-header-cef3

您可以尝试使用" - 单一流程"来启动CEF强迫它运行单个进程的论点(尽管不推荐使用它,因为它们不会在此配置中测试Chromium - 它只是用于调试)。如果您没有将命令行参数传递给CEF,这可能是您问题的开始。为此,您可以在CefApp派生类中为OnBeforeCommandLineProcessing()添加处理程序,这是CEF创建者在此建议的:http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=12928&p=25732&hilit=main_args#p25717。覆盖最终会看起来像这样:

void ServiceCenterApp::OnBeforeCommandLineProcessing(const CefString& process_type,
                                                 CefRefPtr<CefCommandLine> command_line) {

if(!command_line->HasSwitch("single-process")) {
    command_line->AppendSwitch("single-process");
}

}

但是我没有看到你定义一个CefApp派生类,这将是CefInitialize()的一个参数。例如,cefclient样本在wWinMain()中有这个:

 // SimpleApp implements application-level callbacks. It will create the first
  // browser instance in OnContextInitialized() after CEF has initialized.
  CefRefPtr<SimpleApp> app(new SimpleApp);

接着是

  // Initialize CEF.
  CefInitialize(main_args, settings, app.get(), sandbox_info);

你告诉CEF使用派生的App,你可以覆盖你需要的任何处理程序。您可能希望从simple_app示例开始,以获得非常基本的覆盖。

对于调试问题,请尝试附加到启动的所有进程,假设我不正确并且多个进程正在正确启动。