Генерация нескольких файлов * .oct * из одного исходного файла * .cc * для взаимодействия библиотеки C с Octave

     /**
       * 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;
      }
3
задан Pedro H. N. Vieira 16 January 2019 в 19:46
поделиться

4 ответа

Смысл второй ссылки в том, что вы не загружаете файл .oct с несколькими функциями в нем - по крайней мере, с точки зрения октавы. Для этого нужны символические ссылки - там есть символы A, B и C? Сделайте символические ссылки A.oct, B.oct и C.oct, которые указывают на этот файл, и вы можете использовать их так, как если бы каждая содержала только символ, который вам небезразличен.

0
ответ дан Carl Norum 16 January 2019 в 19:46
поделиться

Если у вас есть несколько определений функций в одном октавном файле, вы используете autoload(). Итак, если у вас есть foo.oct с функциями foo и bar, то вы делаете:

autoload ("bar", "path-to-foo.oct");
0
ответ дан carandraug 16 January 2019 в 19:46
поделиться

Еще одна возможность генерировать интерфейс 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
0
ответ дан Pedro H. N. Vieira 16 January 2019 в 19:46
поделиться

Я начну с уточнения второго окна цитаты в вашем вопросе. Это не относится конкретно к определенным функциям .oct. Это подразумевает разницу между канонической функцией, определенной в m-файле, и функциями «на месте», определенными непосредственно в консоли или как часть скрипта.

Что касается первого окна кавычек, когда дело доходит до функций, которые определены в файлах .oct, ситуация другая. Это говорит о том, что вы можете создать файл .oct, который определяет множество функций, но для того, чтобы вызвать эти функции, в вашем пути должен быть файл с тем же именем. , Таким образом, если файл .oct определяет функции "foo" и "bar", вам нужно переименовать одну копию файла .oct с именем "foo.oct", а другую (или, более реалистично, в виде символической ссылки на оригинал) как "bar.oct".

Аналогично, вы также можете определить файл «foo.m» и «bar.m» в вашей рабочей области, который содержит только документацию для этих функций, например, если вы затем выполните «help foo» или « Панель справки "вы получите нужную документацию.

В качестве альтернативы вы можете использовать автозагрузку , как предложил carandraug.

0
ответ дан Tasos Papastylianou 16 January 2019 в 19:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: