Found an issue with the book? Report it on Github.

외부 함수(External Functions)

외부 함수(External Functions)

외부(external)

보간(Interpolation) 관련 예제인 InterpolateExternalVector 함수에서 보았듯이 모델리카로 작성되지 않은 함수를 호출하는 것이 가능합니다.일반적으로 이러한 함수는 C 또는 Fortran으로 작성 됩니다.모델리카는 외부에서 구현된 함수를 algorithm 섹션에 포함하지 않는 대신, 외부 함수에 대한 정보와 함수에서 정보를 전달하는 방법을 제공하는 external 문을 사용하여 호출 합니다.

외부에서 구현된 함수에 대한 최소한의 요구 사항은 external 키워드만 포함하는 것입니다. 예를 들어, 아래와 같습니다.

external;

이 경우 함수가 C로 구현되고 함수 이름이 모델리카 "래퍼(wrapper)" 함수 이름과 일치하며, C에서의 인수가 모델리카 함수에 대한 input 인수가 됩니다.

보간(Interpolation) 예제에 표시된 VectorTable 자료형에서 발견되는 것과 같은 약간 더 복잡한 경우를 살펴 보겠습니다.

  function destructor "Release storage"
    input VectorTable table;
    external "C" destroyVectorTable(table)
      annotation ...
  end destructor;

함수의 구현 언어가 여기에서는 "C" 로 명시적으로 지정되었음을 알 수 있고, "FORTRAN 77""builtin" 이라는 두 가지 다른 가능한 값이 있습니다. (여기서, "builtin" 의 사용은 주로 모델리카 시뮬레이션 소프트웨어 공급업체에서 관심을 가지는 키워드 입니다.)

위의 예제에서 보면 함수의 이름이 명시적으로 지정되었음을 알 수 있습니다.그리고, destroyVectorTable(table) 을 읽는 external 문 부분은 어떤 데이터를 어떤 순서로 외부 함수에 전달해야 하는지 지정합니다.

경우에 따라 외부 함수에 전달된 일부 값을 지정하고 함수 호출 결과가 출력 변수에 매핑되는 방식을 지정해야 할 수 있는데, 다음 function 에서 이런 종류의 예제를 확인할 수 있습니다.

  function constructor
    input Real ybar[:,2];
    output VectorTable table;
    external "C" table=createVectorTable(ybar, size(ybar,1))
      annotation ...
  end constructor;

여기에서 외부 함수는 ybar 배열의 크기를 알아야 하는데, 정보가 함수에 직접 전달되지 않기 때문입니다.또한 createVectorTable 의 결과를 output 변수 table 에 할당해야 합니다. C 함수의 반환 값은 모델리카 함수의 반환 값으로 처리되어야 하는 것이 당연해 보일 수 있지만, 경우에 따라 output 변수를 함수의 인수로 전달해야 합니다. 곧 보게 되겠지만 이러한 경우 외부 함수가 이러한 변수에 값을 할당할 수 있도록 포인터를 사용합니다.

데이터 맵핑(Data Mapping)

C

다음 표는 데이터를 외부 함수 전달할 때 모델리카 자료형이 네이티브 C 자료형으로 매핑하는 방법을 보여줍니다.

Modelica

C (input arguments)

C (output arguments)

Real

double

double *

Integer

int

int *

Boolean

int

int *

String

const char *

const char **

T[d1]

T' *, size_t d1

T' *, size_t d1

T[d1,d2]

T' *, size_t d1, size_t d2

T' *, size_t d1, size_t d2

T[d1,...,dn]

T' *, size_t d1, ..., size_t dn

T' *, size_t d1, ..., size_t dn

size(...)

size_t

N/A

enumeration

int

int *

record

struct *

struct *

이 테이블에 대한 몇 가지 추가 설명을 하겠습니다. 첫째, 모든 문자열이 null(\0)로 종료된다고 가정합니다. 또한 배열의 경우 T' 자료형은 모델리카 자료형 T 가 매핑될 C 자료형을 나타냅니다(동일한 테이블 사용).마지막으로 records 는 C 구조의 멤버가 모델리카 record 의 멤버에 해당하는 C의 구조체(struct) 에 매핑됩니다. record 의 멤버 자료형은 이 테이블의 두 번째 열을 사용하여 매핑됩니다(즉, 마치 입력 인수인 것처럼).

C 함수에서 반환된 데이터의 경우 다음 매핑이 적용됩니다.

Modelica

C

Real

double

Integer

int

Boolean

int

String

const char *

T[d1]

T' *, size_t

T[d1,d2]

T' *, size_t d1, size_t d2

T[d1,...,dn]

T' *, size_t d1, ..., size_t dn

size(...)

size_t

enumeration

int

record

struct *

Fortran

Fortran 함수 또는 서브루틴으로 작업해야 하는 경우 다음 자료형의 매핑이 적용됩니다.

Modelica

Fortran

Real

DOUBLE PRECISION

Integer

INTEGER

Boolean

LOGICAL

T[d1]

T', INTEGER

T[d1,d2]

T', INTEGER d1, INTEGER d2

T[d1,...,dn]

T', INTEGER d1, ..., INTEGER dn

size(...)

INTEGER

enumeration

INTEGER

이 테이블에 대해 주목해야 할 두 가지 중요한 사항이 있습니다. 첫째, 문자열이나 레코드에 대한 매핑이 없습니다.둘째, Fortran은 참조에 의한 전달을 사용하기 때문에 함수로 전달하거나 전달받는 모든 변수는 포인터로 간주됩니다.이러한 이유로 변수가 모델리카 함수의 입력인지 출력인지 구별되지 않습니다.

특별 함수(Special Functions)

모델리카 런타임과 상호 작용하기 위해 외부 함수에서 호출할 수 있는 많은 함수가 있습니다.각 함수에 대해 함수의 이름, 프로토타입 및 함수 목적에 대한 설명을 하겠습니다.

ModelicaVFormatMessage

void ModelicaVFormatMessage(const char*string, va_list);

C 함수 vprintf 와 동일한 형식 제어 하에서 메시지를 출력합니다.

ModelicaError

void ModelicaError(const char* string);

오류 메시지 문자열을 출력합니다(형식 제어 없음). 이 함수는 호출 함수로 반환되지 않지만 모델리카 코드의 어설션과 유사하게 오류를 처리합니다.

ModelicaFormatError

void ModelicaFormatError(const char* string, ...);

C 함수 printf 와 동일한 형식 제어에서 오류 메시지를 출력합니다.이 함수는 호출 함수로 반환되지 않지만 모델리카 코드의 어설션과 유사하게 오류를 처리합니다.

ModelicaVFormatError

void ModelicaVFormatError(const char* string, va_list);

C 함수 vprintf 와 동일한 형식 제어에서 오류 메시지를 출력합니다. 이 함수는 호출 함수로 반환되지 않지만 모델리카 코드의 어설션과 유사하게 오류를 처리합니다.

ModelicaAllocateString

char* ModelicaAllocateString(size_t len);

외부 모델리카 함수의 반환 인수로 사용하는 모델리카 문자열에 대한 메모리를 할당합니다.문자열 배열(= 문자열 배열에 대한 포인터)에 대한 저장소는 다른 배열과 마찬가지로 호출 프로그램에서 여전히 제공된다는 점에 유의해야 합니다.오류가 발생하면 이 함수는 반환하지 않고 ModelicaError 를 호출합니다.

ModelicaAllocateStringWithErrorReturn

char* ModelicaAllocateStringWithErrorReturn(size_t len);

ModelicaAllocateString 과 동일하지만 오류 발생 시 함수가 0을 반환합니다. 이를 통해 외부 함수는 오류 발생 시 파일을 닫고 다른 열린 리소스를 해제할 수 있습니다.리소스를 정리한 후 modelica-error 또는 modelica-format-error를 사용하여 오류를 알립니다.