我有一个C库,我想在Octave中使用。在tutorial之后,似乎很简单:将函数包装在C ++中,然后 mkoctfile 。问题是:如果我想在一个源文件中包含多个函数定义(包装器)怎么办?
在提到的教程中有说明
应注意,在源文件中具有多个DEFUN_DLD函数是完全可以接受的。但是,对于使用DEFUN_DLD宏在源代码中定义的每个函数,必须存在指向oct文件的符号链接,或者应使用自动加载(Function Files)函数。
然后在提供的链接中:
一旦Octave找到一个名称匹配的文件(被调用函数),就会读取该文件的内容。如果定义了单个函数,则将编译并执行该函数。有关如何在单个文件中定义多个功能的更多信息,请参见Script Files。
在第二个链接中,没有有关如何加载其中具有多个功能的 .oct 文件或如何从一个文件生成多个 .oct 文件的信息。单个源文件。据我了解,后面的方法是正确的。我该怎么办?
答案 0 :(得分:4)
第二个链接的要点是,您不要加载其中具有多个功能的 .oct 文件-至少从八度角度来看不是。这就是符号链接的用途-您那里有符号A
,B
和C
?制作指向该文件的A.oct
,B.oct
和C.oct
符号链接,就可以使用它们,就像每个符号都只包含您关心的符号一样。
答案 1 :(得分:3)
如果在一个十进制文件中有多个函数定义,请使用autoload()
。因此,如果您有foo.oct
,它具有函数foo
和bar
,那么您可以:
autoload ("bar", "path-to-foo.oct");
答案 2 :(得分:2)
我将首先澄清您问题中的第二个报价窗口。这不是专门指.oct定义的函数。这意味着规范的m文件定义的功能与直接在控制台中或作为脚本的一部分定义的“现场”功能之间的区别。
对于第一个报价窗口,当涉及到.oct文件中定义的函数时,情况就不同了。这就是说,您可以创建一个定义许多功能的.oct文件,但是为了调用这些功能,在其中需要一个同名的 file 你的路。因此,如果.oct文件定义了函数“ foo”和“ bar”,则需要具有一个名为“ foo.oct”的.oct文件副本,并需要重命名另一个副本(或更实际地,作为指向原始文件的符号链接)作为“ bar.oct”。
类似地,您还可以在工作区中定义“ foo.m”和“ bar.m”文件,该文件仅包含这些函数的文档,例如,如果您随后执行“ help foo”或“ help bar”您将获得所需的文档。
或者,您也可以按照carandraug的建议使用autoload。
答案 3 :(得分:2)
生成C到Octave接口的另一种可能性是使用SWIG,它可以生成具有所有功能的单个 .oct 文件。使用指针和数组时,请参考here。
这里是一个例子:
标题
/* File: example.h */
int fact(int n);
int fact2(int n1, int n2);
void add(int *x, int *y, int *r);
源
/* File: example.c */
#include "example.h"
int fact(int n) {
if (n < 0){ /* This should probably return an error, but this is simpler */
return 0;
}
if (n == 0) {
return 1;
}
else {
/* testing for overflow would be a good idea here */
return n * fact(n-1);
}
}
int fact2(int n1, int n2) {
return fact(n1)*fact(n2);
}
void add(int *x, int *y, int *r) {
*r = *x + *y;
}
界面
/* File example.i */
%module swigexample
%include "cpointer.i"
%{
#include "example.h"
%}
%pointer_functions(int, intp)
%include "example.h"
编译
swig -octave -o swigexample.cpp example.i
mkoctfile -I. -I/usr/include/octave-4.2.2/ -Iswiglib swigexample.cpp example.c
测试
% File test.m
swigexample;
fact(5)
fact2(4,4)
% ==============
a = new_intp();
intp_assign(a, 37);
b = new_intp();
intp_assign(b, 22);
c = new_intp();
add(a,b,c);
r = intp_value(c);
delete_intp(a);
delete_intp(b);
delete_intp(c);
r