我试图为 C++ 库构建 ruby 扩展。首先,我将 C++ 代码包装到 C 中。我使用 Eclipse IDE 构建它,它工作正常。然后我尝试为那个 C 源代码构建 ruby 扩展。这是我尝试过的代码。
/* * Circle.h * * 创建于:2013 年 9 月 18 日 * 作者:kelum */
#ifndef CIRCLE_H_
#define CIRCLE_H_
namespace lemon{
class Circle {
public:
Circle(float radius):_radius(radius) {}
float getArea() { return 3.14159 * _radius * _radius; }
private:
float _radius;
};
}
/* * Circle_w.h * * 创建于:2013 年 9 月 18 日 * 作者:kelum */
#ifndef CIRCLE_W_H_
#define CIRCLE_W_H_
#ifdef __cplusplus
extern "C" {
#endif
extern void *Circle_C_new(float radius);
extern void *Circle_C_delete(void *circle);
extern float Circle_C_getArea(void *circle);
#ifdef __cplusplus
}
#endif
#endif /* CIRCLE_W_H_ */
/* * Circle_w.cpp * * 创建于:2013 年 9 月 18 日 * 作者:kelum */
#include "Circle_w.h"
#include "Circle.h"
using namespace lemon;
extern void *Circle_C_new(float radius) {
return new Circle(radius);
}
extern void *Circle_C_delete(void *circle) {
Circle *c = (Circle *)circle;
//delete c;
return c;
}
extern float Circle_C_getArea(void *circle) {
Circle *c = (Circle *)circle;
return c->getArea();
}
main.c
#include "Circle_w.h"
#include <stdio.h>
#include <stdlib.h>
int main() {
float radius = 1.5;
// Get a pointer to a Circle object
void *circle = Circle_C_new(radius);
// Pass the Circle object to the wrapper methods
float area = Circle_C_getArea(circle);
printf ("Circle of radius %f has area %f\n", radius, area);
// Free the Circle object memory
void *pointer=Circle_C_delete(circle);
return 0;
}
这项工作很好。然后我使用 Circle_w.h 头文件构建 C 文件。这个文件。
#include "ruby.h"
#include "Circle_w.h"
#include <stdio.h>
extern VALUE method_test(){
float r=1.5;
void *circle = Circle_C_new(r);
int area = (int)Circle_C_getArea(circle);
printf("area %d \n",area);
return INT2NUM(area);
}
extern void Init_TestLemon() {
VALUE lemon = rb_define_module("TestLemon");
rb_define_method(lemon, "test", method_test, 0);
}
extconf.rb 文件
require 'mkmf'
extension_name = 'TestLemon'
dir_config(extension_name)
create_makefile(extension_name)
这是我用来测试模块的 ruby 类。
test.rb 文件
require '/home/kelum/workspace/Test/TestLemon'
include TestLemon
puts test
问题是我怎样才能把它编译在一起?当我只运行 extconf.rb 和 test.rb 时,它显示错误。
TestLemon.so: undefined symbol: Circle_C_new
我认为这是因为 extconf.rb 不执行包装 C++ 的构建。我怎样才能使这项工作?非常感谢。