3

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)

これはモジュールのテストに使用したルビークラスです。

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++ のラッピングのビルドを実行していないためだと思います。どうすればこれを機能させることができますか? どうもありがとう。

4

0 に答える 0