외부 함수 인터페이스
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
외부 함수 인터페이스(FFI)는 프로그래밍 언어 간의 호출을 가능하게 하는 기능으로, 주로 하나의 언어(호스트 언어)가 다른 언어(게스트 언어)의 함수를 호출할 수 있게 해준다. FFI는 호스트 언어의 의미 체계와 호출 규약을 게스트 언어의 의미 체계 및 호출 규약과 연결하며, 런타임 환경과 애플리케이션 바이너리 인터페이스도 고려한다. 구현 방식은 라이브러리 사용, 자동 래핑 도구, 래퍼 라이브러리, 호스트 언어 기능 제한 등 다양하다. FFI는 가비지 컬렉션, 객체 및 데이터 유형 매핑, 가상 머신 사용, 언어 간의 상속과 같은 문제로 인해 복잡해질 수 있다. 여러 프로그래밍 언어에서 FFI를 지원하며, 클로저와 자바, 엘릭서와 얼랭처럼 동일한 가상 머신으로 컴파일되는 언어 간에는 FFI가 아닌 다른 방식으로 상호 작용한다.
더 읽어볼만한 페이지
- 함수 (프로그래밍) - 사용자 정의 함수
사용자 정의 함수는 프로그래밍 언어와 데이터베이스 시스템에서 사용자가 직접 정의하여 재사용할 수 있는 코드 블록이다. - 함수 (프로그래밍) - 코루틴
코루틴은 실행을 멈췄다가 다시 시작할 수 있는 서브루틴의 특별한 형태로, 로컬 데이터를 보존하며 다양한 방식으로 구현되고 여러 프로그래밍 상황에서 유용하게 쓰인다. - API - Tk (소프트웨어)
Tk는 Tcl 스크립팅 언어의 크로스 플랫폼 GUI 툴킷으로, 다양한 플랫폼 이식과 여러 프로그래밍 언어 바인딩을 지원하며 사용자 정의 가능한 위젯들을 제공한다. - API - ASIO
ASIO는 독일 스타인버그에서 개발한 오디오 입출력 API 규격으로, 낮은 지연 시간과 멀티 채널 I/O를 지원하며 윈도우 운영체제에서 주로 사용된다. - 컴퓨터에 관한 - 고속 패킷 접속
고속 패킷 접속(HSPA)은 3세대 이동통신(3G)의 데이터 전송 속도를 높이는 기술 집합체로, 고속 하향/상향 패킷 접속(HSDPA/HSUPA)을 통해 속도를 개선하고 다중 안테나, 고차 변조, 다중 주파수 대역 활용 등의 기술로 진화했으나, LTE 및 5G 기술 발전으로 현재는 상용 서비스가 중단되었다. - 컴퓨터에 관한 - 데이터베이스
데이터베이스는 여러 사용자가 공유하고 사용하는 정보의 집합으로, 데이터베이스 관리 시스템을 통해 접근하며, 검색 및 갱신 효율을 높이기 위해 고도로 구조화되어 있고, 관계형, NoSQL, NewSQL 등 다양한 모델로 발전해왔다.
외부 함수 인터페이스 | |
---|---|
기본 정보 | |
유형 | 인터페이스 (컴퓨터 과학) |
설명 | 프로그래밍 언어가 다른 언어로 작성된 루틴을 호출하거나 해당 언어의 서비스를 이용할 수 있도록 하는 메커니즘 |
목적 | |
목적 | 다른 프로그래밍 언어로 작성된 루틴을 호출하거나 서비스를 사용 |
사용 사례 | |
다른 언어의 라이브러리 사용 | 다른 언어로 작성된 라이브러리 또는 운영 체제 서비스에 대한 액세스 허용 |
성능 향상 | 성능에 중요한 작업을 어셈블리어와 같은 저수준 언어로 구현 |
시스템 프로그래밍 | 운영 체제와 상호 작용하는 프로그램 작성 |
레거시 코드 통합 | 새로운 환경에서 레거시 코드를 재사용 |
구현 | |
구현 방법 | C 헤더 파일 구문 분석 외부 언어 구조와 데이터 구조에 대한 자체 설명 인터페이스 |
일반적인 접근 방식 | |
스텁 | 외부 함수에 대한 프록시 역할을 하는 코드 조각 생성 |
마샬링 | 한 언어의 데이터 표현을 다른 언어의 표현으로 변환 |
호출 규약 | 함수에 인수를 전달하고 반환 값을 처리하는 규칙 정의 |
이점 | |
코드 재사용 | 기존 코드베이스 활용 |
상호 운용성 | 다양한 기술 간의 통합 가능 |
유연성 | 프로그래밍 언어 선택의 자유 제공 |
단점 | |
복잡성 | 구현 및 유지 관리가 어려울 수 있음 |
오버헤드 | 언어 간 데이터 변환으로 인한 성능 저하 가능성 |
보안 위험 | 잘못된 사용으로 인한 보안 취약점 발생 가능성 |
예시 | |
예시 | Java Native Interface (JNI) (자바) Common Language Runtime (CLR) (닷넷) C Foreign Function Interface (CFFI) (파이썬) CFFI User Manual (공통 리스프) FFI Introduction (하스켈) |
프로그래밍 언어별 FFI | |
C | 일반적으로 다른 언어에서 C 함수를 호출하는 데 사용됨 |
자바 | JNI를 통해 네이티브 코드를 호출할 수 있음 |
파이썬 | CFFI 및 ctypes 라이브러리를 통해 C 코드를 호출할 수 있음 |
공통 리스프 | CFFI를 통해 C 코드를 호출할 수 있음 |
하스켈 | FFI를 통해 C 코드를 호출할 수 있음 |
주의 사항 | |
메모리 관리 | 언어 간 메모리 관리 방식의 차이점에 주의해야 함 |
예외 처리 | 언어 간 예외 처리 방식의 차이점에 주의해야 함 |
스레드 안전성 | 다중 스레드 환경에서 안전하게 작동하도록 코드를 작성해야 함 |
2. 명칭
이 용어는 공통 리스프의 명세에서 유래되었으며, 이는 언어 간 호출을 가능하게 하는 프로그래밍 언어 기능을 명시적으로 지칭한다. 이 용어는 해석기 및 컴파일러 문서에서 하스켈,[1] 러스트,[2] PHP,[3] 파이썬, 그리고 LuaJIT (루아)[12][4] 등에 의해 공식적으로 사용되는 경우가 많다.[5] 다른 언어들은 다른 용어를 사용한다. 에이다는 ''언어 바인딩''을, 자바는 ''자바 네이티브 인터페이스''(JNI) 또는 ''자바 네이티브 액세스''(JNA)를 사용한다. 외부 함수 인터페이스는 이러한 서비스를 제공하는 메커니즘에 대한 일반적인 용어가 되었다.
외부 함수 인터페이스(FFI)의 주된 기능은 하나의 프로그래밍 언어(FFI를 정의하는 언어, 즉 '호스트' 언어)의 의미 체계와 호출 규약을 다른 언어('게스트' 언어)의 의미 체계 및 호출 규약과 결합하는 것이다. 이 과정은 두 언어의 런타임 환경과 애플리케이션 바이너리 인터페이스도 고려해야 한다. 이는 다음과 같은 여러 가지 방법으로 수행할 수 있다.[29]
3. 동작 방식
FFI는 다음과 같은 사항에 의해 복잡해질 수 있다.[30]
4. 구현 및 사용 시 주의사항
FFI는 다음과 같은 사항에 의해 복잡해질 수 있다.
- 한 언어가 가비지 컬렉션(GC)을 지원하고 다른 언어는 지원하지 않는 경우, GC를 지원하지 않는 언어 코드가 다른 언어의 GC가 실패하도록 하는 일이 없도록 주의해야 한다. 예를 들어, JNI에서 C 코드가 Java로부터 받은 객체 참조를 "유지"하는 경우, 이 정보를 Java 가상 머신 또는 Java 런타임 환경(JRE)에 성공적으로 전달해야 한다. 그렇지 않으면 Java가 C가 해당 객체를 완료하기 전에 객체를 삭제할 수 있다. (C 코드는 C가 해당 객체를 더 이상 필요로 하지 않는 즉시 그러한 객체에 대한 링크를 명시적으로 해제해야 한다.)[6]
- 복잡하거나 사소하지 않은 객체 또는 데이터 유형은 한 환경에서 다른 환경으로 매핑하기 어려울 수 있다.[6]
- 위에서 언급한 매핑 문제로 인해 두 언어가 변경 가능한 객체의 동일한 인스턴스에 대한 참조를 유지하는 것이 불가능할 수 있다.[6]
- 한 언어 또는 두 언어 모두 가상 머신(VM)에서 실행될 수 있다. 더욱이, 두 언어 모두에서 실행되는 경우, 이것들은 종종 다른 VM이다.[6]
- 언어 간의 상속 및 기타 차이점(예: 타입 시스템 간 또는 객체 구성 모델 간)은 특히 어려울 수 있다.[6]
5. FFI의 예
- Ada는 외부 함수를 호출할 수 있을 뿐만 아니라 해당 함수와 메서드를 비 Ada 코드에서 호출할 수 있도록 내보낼 수도 있다.[6]
- C++는 C와 상당한 공통 하위 집합을 공유하므로 C와 간단한 FFI를 가지고 있다. C++에서 extern "C"|영어 선언의 주요 효과는 C++ 이름 맹글링을 비활성화하는 것이다. 다른 언어의 경우 별도의 유틸리티 또는 미들웨어가 사용되며, 예로는 다음이 있다.
- * GNOME 프로젝트: GObject Introspection
- * SWIG
- * 크로미움 프로젝트: Blink 및 V8 엔진은 표준 JavaScript 인터페이스에 인터페이스 설명 언어 (IDL) 컴파일러를 사용한다.
- * 기타 IDL 컴파일러
- Clean은 C 또는 stdcall 호출 규약을 따르는 모든 언어와 양방향 FFI를 제공한다.[7][8]
- Common Lisp
- Compiled Native Interface (CNI), GNU 컴파일러 환경에서 사용되는 JNI의 대안.
- 컴포넌트 객체 모델의 기반 중 하나는 공통 인터페이스 형식이며, 문자열과 배열에 대해 기본적으로 Visual Basic과 동일한 유형을 사용한다.
- D는 C++와 동일한 방식으로 extern "C"|영어를 통해 extern (C++)|영어을 수행한다.
- Dart에는 모바일, 명령줄 및 서버 애플리케이션을 위해 네이티브 C 코드를 호출하는 dart:ffi[9] 라이브러리가 포함되어 있다.
- 동적 프로그래밍 언어는 파이썬, 펄, Tcl, 루비와 같이 C, C++, 또는 C/C++ 호출 규약을 따르는 다른 언어로 작성된 네이티브 코드에 쉽게 접근할 수 있도록 한다.
- Factor는 C, 포트란, Objective-C, Windows COM에 대한 FFI를 가지고 있다. 이들은 모두 임의의 공유 라이브러리를 동적으로 가져오고 호출할 수 있게 한다.
- Fortran 2003에는 상호 운용 가능한 데이터 유형 (내재적 유형과 POD 구조 모두), 상호 운용 가능한 포인터, 상호 운용 가능한 전역 데이터 저장소, Fortran에서 C를 호출하고 C에서 Fortran을 호출하기 위한 메커니즘을 제공하는 모듈 ISO_C_BINDING이 있다.[10] 이 기능은 Fortran 2018 표준에서 개선되었다.
- Go는 `"C"`|영어 가상 패키지를 통해 C 코드를 직접 호출할 수 있다.[11]
- Google 웹 툴킷 (GWT)는 Java가 JavaScript로 컴파일되며, Java 소스 코드가 임의의 JavaScript 함수를 호출하고 JavaScript가 Java로 다시 호출할 수 있도록 하는 JSNI라는 FFI를 가지고 있다.
- Haskell
- Java 네이티브 인터페이스 (JNI)는 Java와 C/C++ 간의 인터페이스를 제공하며, Java가 배포되는 대부분의 시스템에서 선호되는 시스템 언어이다. Java 네이티브 액세스 (JNA)는 접착 코드를 작성하지 않고 네이티브 라이브러리와의 인터페이스를 제공한다. 또 다른 예는 JNR이다.
- LuaJIT는 Lua의 JIT 구현으로, "순수 Lua 코드에서 외부 C 함수를 호출하고 C 데이터 구조를 사용할" 수 있는 FFI를 가지고 있다.[12]
- Nim은 C, C++, Objective-C의 소스를 사용할 수 있게 하는 FFI를 가지고 있다. 또한 JavaScript와도 인터페이스할 수 있다.
- JavaScript는 일반적으로 시스템 라이브러리에 직접 접근하거나 실행할 명령을 제공하지 않는 웹 브라우저 런타임 내에서 실행되지만, 몇 가지 예외가 있다.
- * Node.js는 미리 컴파일된 모듈을 열어 비 내장 리소스에 대한 접근을 제공할 수 있는 기능을 제공한다.
- * Deno는 함수를 통해 일종의 FFI 인터페이스를 제공한다.[13]
- * Bun은 네이티브 라이브러리를 JavaScript에서 직접 효율적으로 호출하기 위해 라는 내장 모듈을 제공한다.[14]
- Julia는 C (및 Fortran과 같은 다른 언어)를 호출하기 위해 키워드를 사용한다.[15], 반면 Python[16] (예: OO 지원 및 GC 지원을 제공하기 위해), Java (및 Scala와 같은 다른 JDK 언어 지원) 및 R과 같은 일부 언어에 대해 유사한 보일러플레이트 없는 지원을 제공하는 패키지를 사용할 수 있다. C++와의 대화형 사용은 Cxx.jl 패키지로도 가능하다.
- PhoneGap (이전 이름은 Apache Callback이었지만 현재 Apache Cordova)은 HTML, CSS 및 JavaScript를 사용하여 네이티브 모바일 애플리케이션을 빌드하기 위한 플랫폼이다. 또한 가속도계, 카메라 (PhotoLibrary 및 SavedPhotoAlbum 포함), 나침반, 저장소 (SQL 데이터베이스 및 localStorage), 알림, 미디어 및 캡처 (오디오 및 비디오 재생 및 녹음), 파일, 연락처 (주소록), 이벤트, 장치 및 연결 정보를 포함한 모바일 전화의 네이티브 기능의 메서드와 속성에 접근하기 위한 JavaScript 콜백 함수를 통해 FFI를 가지고 있다.
- PHP는 C에 FFI를 제공한다.[17]
- 파이썬은 ctypes 및 cffi 모듈을 제공한다. 예를 들어, ctypes 모듈은 공유 라이브러리 또는 동적 연결 라이브러리 (DLL)에서 C 함수를 즉시 로드하고 다음과 같이 파이썬과 C 의미 체계 간에 간단한 데이터 유형을 자동으로 변환할 수 있다.
```python
import ctypes
libc = ctypes.CDLL('/lib/libc.so.6') # 리눅스/유닉스 환경
t = libc.time(None) # 동등한 C 코드: t = time(NULL)
print(t)
```
- P/Invoke는 Microsoft Common Language Runtime과 네이티브 코드 간의 인터페이스를 제공한다.
- Racket은 임의의 공유 라이브러리를 동적으로 가져올 수 있는 매크로를 기반으로 하는 네이티브 FFI를 가지고 있다.[18][19]
- Raku는 루비, 파이썬, 펄, Brainfuck, Lua, C, C++, Go, Scheme (Guile, Gambit), Rust를 호출할 수 있다.[20][21]
- 루비는 ffi 젬 또는 표준 라이브러리 fiddle를 통해 FFI를 제공한다.
```ruby
require 'fiddle'
libm = Fiddle.dlopen('/lib/libm.so.6')
# 다음과 동일: double floor(double x);
floor = Fiddle::Function.new(
libm.sym('floor'), # ptr은 Fiddle::Handle의 참조된 함수(, 또는 기호)이다.
[Fiddle::TYPE_DOUBLE], # args는 ptr 함수에 전달되는 인수 배열이다.
Fiddle::TYPE_DOUBLE # ret_type은 함수의 반환 유형이다.
)
# 다음과 동일: floor(3.14159);
floor.call(3.14159) #=> 3.0
```
- Rust는 다양한 표준 애플리케이션 바이너리 인터페이스 (ABI)를 가진 함수에 대한 외부 함수 인터페이스를 정의한다.[22] Elixir와 인터페이스하기 위한 라이브러리 Rustler도 있다.
- Visual Basic는 비 유니코드 C 함수를 호출할 수 있는 선언적 구문을 가지고 있다.
- Wolfram 언어는 Wolfram Symbolic Transfer Protocol (WSTP)이라는 기술을 제공하며, 이를 통해 C++, Java, .NET 및 기타 언어에 대한 바인딩을 통해 다른 언어 간의 양방향 코드 호출이 가능하다.
- Zig는 내장된 함수를 사용하여 C에 FFI를 제공한다.[23]
6. 특수한 경우
클로저와 자바, 엘릭서와 얼랭처럼 여러 언어가 동일한 바이트코드 가상 머신으로 컴파일되는 경우가 있다. 엄밀히 말하면 인터페이스가 없으므로 FFI는 아니지만, 사용자에게 동일한 기능을 제공한다.
참조
[1]
웹사이트
FFI Introduction
https://wiki.haskell[...]
2015-06-19
[2]
웹사이트
std::ffi
https://doc.rust-lan[...]
2021-04-01
[3]
웹사이트
PHP FFI Manual
https://www.php.net/[...]
2023-08-31
[4]
서적
Ways Ahead: Proceedings of the First International Csound Conference
https://www.worldcat[...]
Cambridge Scholars Publishing
2013
[5]
웹사이트
CFFI documentation
https://cffi.readthe[...]
2015-06-19
[6]
웹사이트
Interface to Other Languages
http://www.adaic.org[...]
Adaic.org
2013-09-29
[7]
웹사이트
Foreign Export
https://cloogle.org/[...]
2020-05-25
[8]
웹사이트
Calling C From Clean
https://svn.cs.ru.nl[...]
2018-04-25
[9]
웹사이트
dart:ffi library
https://api.dartlang[...]
2020-01-01
[10]
웹사이트
'fortran-iso-c-binding' tag wiki
https://stackoverflo[...]
[11]
웹사이트
cgo
https://golang.org/c[...]
2015-08-23
[12]
웹사이트
FFI Library
http://luajit.org/ex[...]
Luajit.org
2013-09-29
[13]
웹사이트
Foreign Function Interface {{!}} Manual
https://deno.land/ma[...]
2023-02-08
[14]
웹사이트
FFI API
https://bun.sh/docs/[...]
[15]
웹사이트
Calling C and Fortran Code
https://docs.juliala[...]
2018-02-11
[16]
간행물
PyCall.jl: Package to call Python functions from the Julia language
https://github.com/J[...]
JuliaPy
2018-02-08
[17]
웹사이트
PHP: FFI - Manual
https://www.php.net/[...]
The PHP Group
2019-06-13
[18]
웹사이트
The Racket Foreign Interface
http://docs.racket-l[...]
Docs.racket-lang.org
2013-09-29
[19]
웹사이트
TR600.pdf
http://repository.re[...]
2013-09-29
[20]
웹사이트
Inline implementations
https://modules.perl[...]
2017-08-15
[21]
웹사이트
Native Call
https://docs.perl6.o[...]
2017-08-15
[22]
웹사이트
Using extern Functions to Call External Code
https://doc.rust-lan[...]
2019-06-01
[23]
웹사이트
Import from C Header File
https://ziglang.org/[...]
Zig Software Foundation
2021-03-11
[24]
웹사이트
4. A sample script
http://www.gimp.org/[...]
Gimp.org
2013-09-29
[25]
웹사이트
Script-Fu and plug-ins for The GIMP
http://www.gimp.org/[...]
Gimp.org
2013-09-29
[26]
문서
http://www.clisp.org[...]
[27]
문서
http://www.haskell.o[...]
[28]
문서
http://www.adahome.c[...]
[29]
문서
http://www.c2.com/cg[...]
[30]
문서
http://www.cse.unsw.[...]
[31]
웹인용
CFFI User Manual
https://common-lisp.[...]
common-lisp.org
2015-06-18
[32]
웹인용
FFI Introduction
https://wiki.haskell[...]
2015-06-19
[33]
웹인용
CFFI documentation
https://cffi.readthe[...]
2015-06-19
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com