/**
* Get the method name for a depth in call stack. <br />
* Utility function
* @param depth depth in the call stack (0 means current method, 1 means call method, ...)
* @return method name
*/
public static String getMethodName(final int depth)
{
final StackTraceElement[] ste = new Throwable().getStackTrace();
//System. out.println(ste[ste.length-depth].getClassName()+"#"+ste[ste.length-depth].getMethodName());
return ste[ste.length - depth].getMethodName();
}
Например, если вы попытаетесь получить линию метода вызова для цели отладки, вам нужно пройти мимо класса Utility, в котором вы кодируете эти статические методы: (старый код java1.4, только для иллюстрируют потенциальное использование StackTraceElement)
/**
* Returns the first "[class#method(line)]: " of the first class not equal to "StackTraceUtils". <br />
* From the Stack Trace.
* @return "[class#method(line)]: " (never empty, first class past StackTraceUtils)
*/
public static String getClassMethodLine()
{
return getClassMethodLine(null);
}
/**
* Returns the first "[class#method(line)]: " of the first class not equal to "StackTraceUtils" and aclass. <br />
* Allows to get past a certain class.
* @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils.
* @return "[class#method(line)]: " (never empty, because if aclass is not found, returns first class past StackTraceUtils)
*/
public static String getClassMethodLine(final Class aclass)
{
final StackTraceElement st = getCallingStackTraceElement(aclass);
final String amsg = "[" + st.getClassName() + "#" + st.getMethodName() + "(" + st.getLineNumber()
+")] <" + Thread.currentThread().getName() + ">: ";
return amsg;
}
/**
* Returns the first stack trace element of the first class not equal to "StackTraceUtils" or "LogUtils" and aClass. <br />
* Stored in array of the callstack. <br />
* Allows to get past a certain class.
* @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils.
* @return stackTraceElement (never null, because if aClass is not found, returns first class past StackTraceUtils)
* @throws AssertionFailedException if resulting statckTrace is null (RuntimeException)
*/
public static StackTraceElement getCallingStackTraceElement(final Class aclass)
{
final Throwable t = new Throwable();
final StackTraceElement[] ste = t.getStackTrace();
int index = 1;
final int limit = ste.length;
StackTraceElement st = ste[index];
String className = st.getClassName();
boolean aclassfound = false;
if(aclass == null)
{
aclassfound = true;
}
StackTraceElement resst = null;
while(index < limit)
{
if(shouldExamine(className, aclass) == true)
{
if(resst == null)
{
resst = st;
}
if(aclassfound == true)
{
final StackTraceElement ast = onClassfound(aclass, className, st);
if(ast != null)
{
resst = ast;
break;
}
}
else
{
if(aclass != null && aclass.getName().equals(className) == true)
{
aclassfound = true;
}
}
}
index = index + 1;
st = ste[index];
className = st.getClassName();
}
if(resst == null)
{
//Assert.isNotNull(resst, "stack trace should null"); //NO OTHERWISE circular dependencies
throw new AssertionFailedException(StackTraceUtils.getClassMethodLine() + " null argument:" + "stack trace should null"); //$NON-NLS-1$
}
return resst;
}
static private boolean shouldExamine(String className, Class aclass)
{
final boolean res = StackTraceUtils.class.getName().equals(className) == false && (className.endsWith("LogUtils"
) == false || (aclass !=null && aclass.getName().endsWith("LogUtils")));
return res;
}
static private StackTraceElement onClassfound(Class aclass, String className, StackTraceElement st)
{
StackTraceElement resst = null;
if(aclass != null && aclass.getName().equals(className) == false)
{
resst = st;
}
if(aclass == null)
{
resst = st;
}
return resst;
}
Смысл второй ссылки в том, что вы не загружаете файл .oct с несколькими функциями в нем - по крайней мере, с точки зрения октавы. Для этого нужны символические ссылки - там есть символы A
, B
и C
? Сделайте символические ссылки A.oct
, B.oct
и C.oct
, которые указывают на этот файл, и вы можете использовать их так, как если бы каждая содержала только символ, который вам небезразличен.
Если у вас есть несколько определений функций в одном октавном файле, вы используете autoload()
. Итак, если у вас есть foo.oct
с функциями foo
и bar
, то вы делаете:
autoload ("bar", "path-to-foo.oct");
Еще одна возможность генерировать интерфейс C - Octave - использовать SWIG , который может генерировать один файл .oct со всеми вашими функциями. См. здесь при использовании указателей и массивов.
Вот пример:
header
/* File: example.h */
int fact(int n);
int fact2(int n1, int n2);
void add(int *x, int *y, int *r);
source
/* 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;
}
interface
/* File example.i */
%module swigexample
%include "cpointer.i"
%{
#include "example.h"
%}
%pointer_functions(int, intp)
%include "example.h"
compile
[113 ]тест
% 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
Я начну с уточнения второго окна цитаты в вашем вопросе. Это не относится конкретно к определенным функциям .oct. Это подразумевает разницу между канонической функцией, определенной в m-файле, и функциями «на месте», определенными непосредственно в консоли или как часть скрипта.
Что касается первого окна кавычек, когда дело доходит до функций, которые определены в файлах .oct, ситуация другая. Это говорит о том, что вы можете создать файл .oct, который определяет множество функций, но для того, чтобы вызвать эти функции, в вашем пути должен быть файл с тем же именем. , Таким образом, если файл .oct определяет функции "foo" и "bar", вам нужно переименовать одну копию файла .oct с именем "foo.oct", а другую (или, более реалистично, в виде символической ссылки на оригинал) как "bar.oct".
Аналогично, вы также можете определить файл «foo.m» и «bar.m» в вашей рабочей области, который содержит только документацию для этих функций, например, если вы затем выполните «help foo» или « Панель справки "вы получите нужную документацию.
В качестве альтернативы вы можете использовать автозагрузку , как предложил carandraug.