質問編集履歴

2

想定通りに動かなかったソースを追記

2017/08/19 03:38

投稿

KureteRubyLua
KureteRubyLua

スコア206

test CHANGED
File without changes
test CHANGED
@@ -297,3 +297,207 @@
297
297
  作った変数の中にあるVectorの配列の一要素を代入できないという事です。
298
298
 
299
299
  もし、他に問題点や聞きたい事があれば指摘をお願いします。
300
+
301
+
302
+
303
+ 二回目の追記
304
+
305
+
306
+
307
+ 想定通りに動かないRubyのソースを書きました。このソースを通すと「0,99」と表示されるはずが「0,0」と表示されてしまいます。
308
+
309
+
310
+
311
+ ```Ruby
312
+
313
+
314
+
315
+ #A_DataはCと連携させたクラス
316
+
317
+ data=A_Data.new()
318
+
319
+ #b_arrayはA_Dataの中にあるstd::vector<int>型の変数
320
+
321
+ #b_arrayに添字を添え、中身を表示する事はできる
322
+
323
+ p data.b_array[0]
324
+
325
+ #data.b_array[0]にbufを代入しているが、何故か代入できない
326
+
327
+ buf=99;
328
+
329
+ data.b_array[0]=buf;
330
+
331
+ p data.b_array[0]
332
+
333
+ ```
334
+
335
+ 上のRubyのA_DataはC++で作成した独自クラスをRubyにバインドした物です。
336
+
337
+ 下のような形でバインドせずに通すとエラーが起きるのでご注意下さい。
338
+
339
+
340
+
341
+ ```C++
342
+
343
+
344
+
345
+ #include <vector>
346
+
347
+ #include "mrubybind.h"
348
+
349
+
350
+
351
+ class AData
352
+
353
+ {
354
+
355
+ protected:
356
+
357
+ std::vector<int> b_array;
358
+
359
+ public:
360
+
361
+ AData()
362
+
363
+ {
364
+
365
+ b_array.resize(1);
366
+
367
+ b_array[0] = 0;
368
+
369
+ };
370
+
371
+ std::vector<int>& GetBArray()
372
+
373
+ {
374
+
375
+ return b_array;
376
+
377
+ }
378
+
379
+ void SetBArray(std::vector<int> set)
380
+
381
+ {
382
+
383
+ b_array=set;
384
+
385
+ }
386
+
387
+ virtual ~AData(){};
388
+
389
+ };
390
+
391
+
392
+
393
+
394
+
395
+ AData* newAData()
396
+
397
+ {
398
+
399
+ return new AData();
400
+
401
+ }
402
+
403
+
404
+
405
+ void installADataClass(mrb_state* mrb)
406
+
407
+ {
408
+
409
+ mrubybind::MrubyBind b(mrb);
410
+
411
+ mrubybind::Type<AData>::TYPE_NAME = "A_Data";
412
+
413
+ b.bind_class("A_Data", newAData);
414
+
415
+ b.bind_instance_method("A_Data", "b_array", &AData::GetBArray);
416
+
417
+ b.bind_instance_method("A_Data", "b_array=", &AData::SetBArray);
418
+
419
+ }
420
+
421
+
422
+
423
+ int main(int argc, char *argv[])
424
+
425
+ {
426
+
427
+ // ファイルを開く
428
+
429
+ const char* fn = "hoge.rb";
430
+
431
+ std::shared_ptr< FILE > file(fopen(fn, "r"), [](FILE* f) { if (f != nullptr) { fclose(f); } });
432
+
433
+
434
+
435
+ // エラー処理は程々に
436
+
437
+ if (file == nullptr) {
438
+
439
+ std::cout << "Load " << fn << " failed." << std::endl;
440
+
441
+ return 1;
442
+
443
+ }
444
+
445
+ // 仮想マシンを初期化して
446
+
447
+ std::shared_ptr< mrb_state > mrb(mrb_open(), [](mrb_state* p) { if (p != nullptr) { mrb_close(p); } });
448
+
449
+ // 一時オブジェクトがつくられるのでGC arenaを保存
450
+
451
+ int ai = mrb_gc_arena_save(mrb.get());
452
+
453
+ mrbc_context *context = mrbc_context_new(mrb.get());
454
+
455
+ installADataClass(mrb.get());
456
+
457
+
458
+
459
+ // 実行する ("Hello, World!" が出る)
460
+
461
+ mrb_load_file(mrb.get(), file.get());
462
+
463
+ if (mrb->exc) {
464
+
465
+ mrb_value exc = mrb_obj_value(mrb->exc);
466
+
467
+
468
+
469
+ // エラー内容を取得
470
+
471
+ mrb_value backtrace = mrb_get_backtrace(mrb.get());
472
+
473
+ puts(mrb_str_to_cstr(mrb.get(), mrb_inspect(mrb.get(), backtrace)));
474
+
475
+
476
+
477
+ // バックトレースを取得
478
+
479
+ mrb_value inspect = mrb_inspect(mrb.get(), exc);
480
+
481
+ puts(mrb_str_to_cstr(mrb.get(), inspect));
482
+
483
+
484
+
485
+ // 例外をクリア
486
+
487
+ mrb->exc = 0;
488
+
489
+ }
490
+
491
+
492
+
493
+ mrb_gc_arena_restore(mrb.get(), ai);
494
+
495
+
496
+
497
+ mrbc_context_free(mrb.get(), context);
498
+
499
+ return 0;
500
+
501
+ }
502
+
503
+ ```

1

ソースコードの改造した部分を追記、問題点について更新

2017/08/19 03:38

投稿

KureteRubyLua
KureteRubyLua

スコア206

test CHANGED
File without changes
test CHANGED
@@ -61,3 +61,239 @@
61
61
 
62
62
 
63
63
  もし足りない部分があれば質問をお願いします。よろしくお願いします。
64
+
65
+
66
+
67
+ 追記
68
+
69
+
70
+
71
+ ソースコードをaxfcにアップしました。
72
+
73
+ https://www.axfc.net/u/3835671
74
+
75
+
76
+
77
+ 改造した部分のみを書くと、こうなります。
78
+
79
+
80
+
81
+ ```C++
82
+
83
+
84
+
85
+ //改造ここから
86
+
87
+
88
+
89
+ //独自クラスでも扱えるように改造
90
+
91
+ template<typename T>
92
+
93
+ struct Type {
94
+
95
+ static T(*SetFunc)(mrb_state* mrb, mrb_value v);
96
+
97
+ static mrb_value(*RetFunc)(mrb_state* mrb, T& p);
98
+
99
+ static const char* TYPE_NAME;
100
+
101
+ static int check(mrb_state* mrb, mrb_value v) { return mrb_class_ptr(v) != nullptr; }
102
+
103
+ static T get(mrb_state* mrb, mrb_value v)
104
+
105
+ {
106
+
107
+ return SetFunc(mrb, v);
108
+
109
+ }
110
+
111
+
112
+
113
+ static mrb_value ret(mrb_state* mrb, T& p)
114
+
115
+ {
116
+
117
+ return RetFunc(mrb, p);
118
+
119
+ }
120
+
121
+ };
122
+
123
+
124
+
125
+ template<typename T>
126
+
127
+ T(*Type<T>::SetFunc)(mrb_state* mrb, mrb_value v);
128
+
129
+
130
+
131
+ template<typename T>
132
+
133
+ mrb_value(*Type<T>::RetFunc)(mrb_state* mrb, T& p);
134
+
135
+
136
+
137
+ template<typename T>
138
+
139
+ const char* Type<T>::TYPE_NAME;
140
+
141
+
142
+
143
+
144
+
145
+ //Vectorを扱えるように改造
146
+
147
+ template<typename T>
148
+
149
+ struct Type<std::vector<T>> {
150
+
151
+ static const char* TYPE_NAME;
152
+
153
+ static int check(mrb_state* mrb, mrb_value v) { return mrb_array_p(v); }
154
+
155
+ static std::vector<T> get(mrb_state* mrb, mrb_value v)
156
+
157
+ {
158
+
159
+ std::vector<T> indexes;
160
+
161
+ int len_i = RARRAY_LEN(v);
162
+
163
+ indexes.resize(len_i);
164
+
165
+ for (int i = 0; i < len_i; ++i)
166
+
167
+ {
168
+
169
+ indexes.push_back(static_cast<T>(Type<T>::get(mrb, v)));
170
+
171
+ }
172
+
173
+ return indexes;
174
+
175
+ }
176
+
177
+ static mrb_value ret(mrb_state* mrb, std::vector<T> p)
178
+
179
+ {
180
+
181
+ mrb_value foo = mrb_ary_new(mrb);
182
+
183
+ for (int i = 0; i < p.size(); ++i)
184
+
185
+ {
186
+
187
+ mrb_ary_push(mrb, foo, Type<T>::ret(mrb, p[i]));
188
+
189
+ }
190
+
191
+ return foo;
192
+
193
+ }
194
+
195
+ };
196
+
197
+ template<typename T>
198
+
199
+ const char* Type<std::vector<T>>::TYPE_NAME = "Array";
200
+
201
+ //Vector
202
+
203
+ template<typename T>
204
+
205
+ struct Type<std::vector<T>&> {
206
+
207
+ static const char* TYPE_NAME;
208
+
209
+ static int check(mrb_state* mrb, mrb_value v) { return mrb_array_p(v); }
210
+
211
+ static std::vector<T> get(mrb_state* mrb, mrb_value v)
212
+
213
+ {
214
+
215
+ std::vector<T> indexes;
216
+
217
+ int len_i = RARRAY_LEN(v);
218
+
219
+ indexes.resize(len_i);
220
+
221
+ for (int i = 0; i < len_i; ++i)
222
+
223
+ {
224
+
225
+ indexes.push_back(static_cast<T>(Type<T>::get(mrb, v)));
226
+
227
+ }
228
+
229
+ return indexes;
230
+
231
+ }
232
+
233
+ static mrb_value ret(mrb_state* mrb, std::vector<T> p)
234
+
235
+ {
236
+
237
+ mrb_value foo = mrb_ary_new(mrb);
238
+
239
+ for (int i = 0; i < p.size(); ++i)
240
+
241
+ {
242
+
243
+ mrb_ary_push(mrb, foo, Type<T>::ret(mrb, p[i]));
244
+
245
+ }
246
+
247
+ //return mrb_ary_value(&p);
248
+
249
+ return foo;
250
+
251
+ }
252
+
253
+ };
254
+
255
+ template<typename T>
256
+
257
+ const char* Type<std::vector<T>&>::TYPE_NAME = "Array";
258
+
259
+
260
+
261
+ //改造ここまで
262
+
263
+
264
+
265
+ //中略
266
+
267
+
268
+
269
+
270
+
271
+ //改造ここから
272
+
273
+ template <class T>
274
+
275
+ void bind_set_func(T(*SetFunc)(mrb_state* mrb, mrb_value v)) {
276
+
277
+ Type<T>::SetFunc = SetFunc;
278
+
279
+ }
280
+
281
+ template <class T>
282
+
283
+ void bind_ret_func(mrb_value(*RetFunc)(mrb_state* mrb, T& p)) {
284
+
285
+ Type<T>::RetFunc = RetFunc;
286
+
287
+ }
288
+
289
+ コード
290
+
291
+ ```
292
+
293
+
294
+
295
+ 問題点はRubyの部分に書いたとおりで、C++で作ったクラスを用いて
296
+
297
+ 作った変数の中にあるVectorの配列の一要素を代入できないという事です。
298
+
299
+ もし、他に問題点や聞きたい事があれば指摘をお願いします。