zoukankan      html  css  js  c++  java
  • Cannot find bounds of current function

    MinGW编译平台的应用程序使用libcef.dll,当调用cef的capi接口时程序崩溃。调试单步到cef capi函数时,调试器报错“Cannot find bounds of current function”。

    解决问题的思路在https://stackoverflow.com/questions/8741493/why-i-do-get-cannot-find-bound-of-current-function-when-i-overwrite-the-ret-ad

    在windows平台需要使用嵌入浏览器cef,同时要使用c++11,又不想安装庞大的VS开发环境。选用了codeblocks-17.12mingw-nosetup作为开妇环境,压缩包不到100MB,MinGW gcc为2015年的5.1.0版本。支持同等c++11特性的vc编译器,应该是VS2015,即使是express版也有5G庞大。

    http://opensource.spotify.com/cefbuilds/index.html#windows32_builds找到最低版本的libcef.3.2704.1414,体积约50M。笔者在其它软件找到体积更小,只有40M的libcef.dll.3.2171。如果不迷恋c++wrapper的话,下载后的cefbuild直接可以使用capi。如果已经习惯了<<inside c++ object model>>的思维和c面向对象的思维,就明白其实cef的capi已经经过面向对象思想设计。

    有了开发环境codeblocks+MinGw,现成的库文件libcef.dll.3.2171,还有接口头文件libcef.3.2704.1414.zip。只要将win32的库文件转换成MinGw的链接库就可以使用。自然就是使用MinGw的工具导出def,然后导出.a库文件。

    经过一番适配调整配置后,程序编译链接成功,但是运行失败了, 调试时gcc在运行cef capi处报错"Cannot find bounds of current function"。

    这个错误并非没有加载到库文件,或者是没有加载到函数,而是函数边界问题。在stackoverflow有post讨论回答“It overwrites the current stack frame of your function with irrelevant data, and destroys the return address in the process, which is normally stored there among other things”。就是函数调用的栈帧被破坏。这事情在win平台开发比较常见, stdcall与cdecl,callee和caller谁负责平衡堆栈的问题,不一致时使得栈帧被破坏。WINAPI以及CALLBACK就是stdcall。而cef项目却有这么一个CEF_CALLBACK对win操作平台下的回调约定,自然就是stdcall。早期cef项目(这里指本文采用的3.27xx于2016年)不考虑对MinGW支持,预编译只有两大平台的分支COMPILER_MSVC与COMPLIER_GCC,诡异的就是MinGW是在WINOS上的GCC,所有十分尴尬。最新版的cef将CEF_CALLBACK的定义单独放置在一个预编译分支OS_WIN。

    CEF_CALLBACK的定义在internal/cef_export.h。下面两个版本的文件对照:

    3.2704.1414

    #if defined(COMPILER_MSVC)
    
    #ifdef BUILDING_CEF_SHARED
    #define CEF_EXPORT __declspec(dllexport)
    #elif USING_CEF_SHARED
    #define CEF_EXPORT __declspec(dllimport)
    #else
    #define CEF_EXPORT
    #endif
    #define CEF_CALLBACK __stdcall
    
    #elif defined(COMPILER_GCC)
    
    #define CEF_EXPORT __attribute__ ((visibility("default")))
    #define CEF_CALLBACK
    
    #endif  // COMPILER_GCC
    
    #endif  // CEF_INCLUDE_INTERNAL_CEF_EXPORT_H_

    78.3.9

    #if defined(COMPILER_MSVC)
    
    #ifdef BUILDING_CEF_SHARED
    #define CEF_EXPORT __declspec(dllexport)
    #elif USING_CEF_SHARED
    #define CEF_EXPORT __declspec(dllimport)
    #else
    #define CEF_EXPORT
    #endif
    
    #elif defined(COMPILER_GCC)
    
    #define CEF_EXPORT __attribute__((visibility("default")))
    
    #endif  // COMPILER_GCC
    
    #if defined(OS_WIN)
    #define CEF_CALLBACK __stdcall
    #else
    #define CEF_CALLBACK
    #endif

    问题迎刃而解。

  • 相关阅读:
    批量修改同一种控件属性
    线程池的使用
    金蝶K3常用数据表
    安装更新
    ApexSQL
    c# 计算一个整型数组的平均
    sqlServer基础知识
    c# 获取字符串数组中最长的的字符串并输出最长的字符串
    c# 获取数组中最大数的值
    c# 计算1-100之间的所有质数(素数)的和
  • 原文地址:https://www.cnblogs.com/bbqzsl/p/11986860.html
Copyright © 2011-2022 走看看