gpt4 book ai didi

c++ - 编译 Ruby C++ 扩展

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:19:20 25 4
gpt4 key购买 nike

我正在尝试为 Ruby 编译一个 C++ 扩展,编译没有返回错误,但它似乎编译不正确。我做错了什么?

我有主要的 cpp 脚本foo.cpp:

#include <iostream>
#include <ruby.h>
extern "C"

VALUE cFoo;
void Init_foo(){cFoo = rb_define_class("Foo", rb_cObject);}

extconf.rb:

require "mkmf"
$libs += " -lstdc++ "
create_makefile("foo")

在这些文件的目录中,我做了

$ ruby extconf.rb
creating Makefile
$ make
compiling foo.cpp
linking shared-object foo.so
$ ls
Makefile extconf.rb foo.cpp foo.o foo.so

然后,我有一个 Ruby 脚本 test.rb:

#!/usr/bin/env ruby
require "path_to_this_directory/foo"

然后我运行 test.rb。它返回一个错误:

... in `require': .../foo.so: undefined symbol: cFoo - .../foo.so (LoadError)

我做错了什么?

环境

  • 操作系统:Ubuntu Linux 11.10
  • ruby :1.9.3

最佳答案

您要声明 cFoo 存在:

extern "C"

VALUE cFoo;

但你永远不会定义它。说 extern "C"blahblah 只是说 blahblah 存在,它是外部可见的,并且它的名字不会被破坏(即“C”链接)但是extern 声明实际上并没有定义任何东西; extern 表示某物存在,但并未使其存在。

您的 C++ 应该更像这样:

#include <iostream>
#include <ruby.h>

extern "C" VALUE cFoo;
extern "C" void Init_foo();

VALUE cFoo;
void Init_foo(){cFoo = rb_define_class("Foo", rb_cObject);}

您需要两个 extern "C" 来告诉 C++ 编译器保留名称,然后单独定义符号。你也可以这样说:

#include <iostream>
#include <ruby.h>

extern "C" VALUE cFoo;

VALUE cFoo;
extern "C" void Init_foo(){cFoo = rb_define_class("Foo", rb_cObject);}

我不确定第二个版本是标准 C++ 还是 GCC 扩展。

我不太喜欢 C++,所以我希望我没有把术语搞得太糟。

关于c++ - 编译 Ruby C++ 扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10167149/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com