草庐IT

c++ - 在编译时检查函数是否具有 C 链接 [无法解决]

coder 2023-11-16 原文

有什么方法可以在编译时检查给定函数是否使用 C 链接声明(即使用 extern "C")?

我正在开发一个插件系统。每个插件都可以为插件加载代码提供工厂函数。但是,这必须通过名称(以及随后使用 GetProcAddressdlsym)来完成。这要求使用 C 链接声明函数,以防止名称修改。如果引用的函数是用 C++ 链接声明的(而不是在运行时发现具有该名称的函数不存在时),那么能够抛出编译器错误会很好。

这是我的意思的一个简化示例:

extern "C" void my_func()
{
}

void my_other_func()
{
}

// Replace this struct with one that actually works
template<typename T>
struct is_c_linkage
{
    static const bool value = true;
};

template<typename T>
void assertCLinkage(T *func)
{
    static_assert(is_c_linkage<T>::value, "Supplied function does not have C-linkage");
}

int main()
{
    assertCLinkage(my_func); // Should compile
    assertCLinkage(my_other_func); // Should NOT compile
}

is_c_linkage 的实现是否会为第二个函数而不是第一个函数抛出编译器错误?我不确定它是否可能(尽管它可能作为编译器扩展存在,我仍然想知道)。谢谢。

最佳答案

我同意 Jonathan Leffler 的观点,这可能无法以标准方式实现。也许这在某种程度上是可能的,具体取决于编译器甚至编译器的版本,但是您必须进行试验以确定可能的方法并接受编译器的行为可能是无意的并且可能在以后的版本中“修复”的事实。

例如,对于 Debian Squeeze 上的 g++ 版本 4.4.4,您可以使用这种方法为不是 stdcall 的函数引发编译器错误:

void my_func() __attribute__((stdcall));
void my_func() { }

void my_other_func() { }

template <typename ret_, typename... args_>
struct stdcall_fun_t
{
    typedef ret_ (*type)(args_...) __attribute__((stdcall));
};

int main()
{
    stdcall_fun_t<void>::type pFn(&my_func),
        pFn2(&my_other_func);
}

g++ -std=c++0x 无法编译此代码,因为:

SO2936360.cpp:17: error: invalid conversion from ‘void ()()’ to ‘void ()()’

第 17 行是 pFn2 的声明。如果我去掉这个声明,那么编译就成功了。

不幸的是,此技术不适用于 cdecl

关于c++ - 在编译时检查函数是否具有 C 链接 [无法解决],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2936360/

有关c++ - 在编译时检查函数是否具有 C 链接 [无法解决]的更多相关文章

  1. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  2. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  3. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  4. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  5. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  6. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  7. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  8. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

    我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

  9. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  10. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

随机推荐