본문 바로가기
Engineering

[LabVIEW] DLL 호출

by 투썬 아빠 2012. 1. 9.



 LabVIEW를 처음 접하는 분들이 궁금해 하는 것 중 하나가 
'쉽고 편리하긴 한데....... 다른 언어와 호환이 어렵지 않은가?' 이다. 
바로 이 궁금증을 해소 할 수 있는 기능이 바로 'DLL 호출'이다.
LabVIEW의 많은 강력한 기능 중 이 것 만큼 강력한 것이 또 있을까?

이 페이지에서는 

LabVIEW Tech-Tip 4호 - LabVIEW에서 공유라이브러리(DLL) 호출 및 생 

의 내용을 참고하여 작성하였습니다.
원문)  
http://korea.ni.com/support/techtip4

※ 이 페이지에서 설명하면서 사용할 예제 파일의 위의 NI 페이지로 가서 다운로드 하길 권합니다.
※ 예제 파일은 7.0 , 8.0 버젼으로 구성되어있습니다.
※ 설명은 LabVIEW 2011 기준으로 하도록 하겠습니다.






본격적인 설명에 들어가기 전에 몇가지 알고 넘어가야 할 것을 보도록 하죠.


공유라이브러리 (DLL)의 이해

DLL로부터 함수를 호출하기 위해 사용자는 다음 4가지의 정보가 필요합니다:

1. 기능에 대한 코드가 존재하는 라이브러리 파일 
2. 라이브러리 안에서 나타나는 함수의 이름
3. 반환 타입을 포함한 요구되는 함수 변수의 개수와 타입
4. 호출 규정

사용자가 라이브러리의 작성자일 경우 사용자는 이 정보를 이미 가지고 있습니다. 타 회사로부터 받은 라이브러리일 경우 이 정보를 모아놓은 라이브러리와 함께 온 문서를 참조해야 할 것입니다.

함수 원형을 찾기 위해 DLL에 함께 포함된 헤더 (.h) 파일을 찾을 필요가 있습니다.

예를 들어 우리가 예제를 통해 호출해 볼 MessageBox의 정보를 갖고 있는 DLL의 경우 다음과 같이 표시가 됩니다:

라이브러리: user32.dll
함수 원형: int MessageBoxA (hWnd, lptext, lpCaption, uType)
호출 규정: 표준


이러한 정보를 갖고 DLL을 호출 하였다고 하더라도 몇 가지 고려해야 할 사항들이 있습니다.
먼저, 서로 다른 플랫폼에서 숫자 데이터 타입의 크기가 일관적으로 사용되지 않는다는 것입니다. LabVIEW는 아래 표와 같이 일관적으로 모든 숫자 데이터 타입을 LabVIEW의 숫자 데이터 타입으로 바꾸어 줌으로써 이러한 문제를 덜어 줍니다.

 

표 1. 다른 플랫폼과 LabVIEW사이의 숫자 데이터 변환

 

또한 사용자는 함수가 요구하는 포인터에 관해 알 필요가 있습니다. 일부 파라미터는 값에 의해 전달되고 일부는 포인터에 의해 전달됩니다. 포인터로 통과되는 것들을 위해 함수는 단일 값 또는 값 배열의 시작 위치를 생각해야 합니다. 성공적으로 라이브러리 함수를 호출해야 할 경우 이 위치를 아는 것은 중요합니다.

마지막으로 알아야 할 것은 C 문자열로 DLL에 일반적으로 전달되는 문자열입니다. C 문자열은 char의 배열이며 일반적으로 "char*"의 함수 원형으로 보여지며 문자 배열의 포인터입니다. 부수적으로 C 함수는 항상 NULL 문자(ASCII value 0x00)와 함께 끝이 나므로 문자열의 끝에 도달했음을 알 수 있습니다
이 모든 정보가 있다면 사용자는 약간의 수정으로 함수 원형을 쓸 수 있습니다(Win32 OS를 사용할 경우).




 
 

 [ 예제 ] LabVIEW에서 DLL을 호출 하는 방법
 

▶ 목적: \WINDOWS\system32\user32.dll에 있는 MessageBoxA 기능을 호출

▶ 예제 수행 준비 단계
먼저 예제 폴더 중 ‘예제 메시지 박스’에 있는 ‘메시지 박스 80.vi’를 엽니다 (LabVIEW 7.0또는 7.1 사용자는 메시지 박스 70.vi). 아래 그림1과 같이 이미 프런트패널이 완성되어 있습니다.


그림 1. 메시지 박스 80.vi 프런트 패널

 

▶ MessageBoxA 기능 정보
다음 그림 2는 MessageBoxA 기능의 항목을 보여줍니다.

 

그림 2. MessageBoxA 함수원형

▶ 반환 유형
이 기능의 반환 유형은 부호가 있는 32비트 정수로 정의됩니다.
Win32 API에는 MessageBoxA 기능의 가능한 반환 값 상수 이름 목록이 있습니다. 이 예에서 가능한 반환 값은 IDABORT, IDRETRY, IDIGNORE이며 각각 십진수 값 3, 4, 5를 갖습니다. 메모리 부족으로 운영 체제가 메시지 상자를 만들 수 없다면 반환 값은 0이 됩니다.

▶ 파라미터들
1. HWnd
이 매개변수는 HWND 데이터 유형이며, winuser.h와 windows.h에 정의되어 있는 대로 부호가 없는 32비트 정수입니다. 이는 만들어질 메시지 상자의 소유자 또는 parents 창을 식별합니다. 이 매개변수가 NULL이면 메시지 상자에는 소유자 창이 없습니다. 본질적으로, hwnd의 유효 값을 전송함으로써 메시지 상자가 어느 창에 속하는지를 파악할 수 있습니다. 하지만 이 창의 parents를 정의할 필요는 없으므로 no parents 또는 NULL을 지정합니다. 상수 NULL은 0입니다.

2. lptext 
이 매개변수는 LPCSTR 데이터 유형으로 상수 문자 문자열을 가리키는 32비트 포인터이며 C 유형(Null-종료) 문자열로 정의됩니다. 이 문자열에는 메시지 박스에 표시하고자 하는 텍스트가 포함됩니다.

3. lpCaption 
이 매개변수는 C 유형의 상수 문자 문자열로서 메시지 박스 창의 제목 표시줄에 표시하고자 하는 이름이 포함됩니다. LPCSTR 데이터 유형이기도 합니다.

4. uType 
이 매개변수는 UINT 데이터 유형으로 부호가 없는 32비트 정수 값으로 정의됩니다. 이 매개변수는 표시되는 메시지 상자의 유형을 결정합니다. 윈도우 API에는 이 기능에 전송될 수 있는 유효 상수의 이름 목록이 있으며, winuser.h에는 실제 10진수 값이 포함될 것입니다. 중단, 다시 시도, 무시 버튼이 있는 대화상자를 만들 것이기 때문에 상수의 이름은 MB_ABORTRETRYIGNORE이며 이는 winuser.h에 있는 값 2를 갖는 것으로 정의됩니다. uType 매개변수에 대해 이 값을 전송합니다. 아래의 표2에는 다른 유형의 메시지 상자 및 이들과 대응하는 uType이 나열되어있습니다.

표 2. uType 데이터 유형

▶ 호출 형식
MessageBoxA 기능의 호출 형식은 winuser.h에서 확인할 수 있습니다. MessageBoxA에 대해 winuser.h에서 검색을 해보면 이 기능 앞에 표준 호출(WINAPI)가 있다는 것을 알게 됩니다. 이는 windef.h에 _stdcall로 정의됩니다.
※ 윈도우 DLL에 대한 설명은 http://msdn.microsoft.com/library/default.aspx에 있는 MSDN Library를 참조하시기 바랍니다.

 

▶ 블록다이어그램

1. 아래 내용을 따라 하시면 다음과 같이 블록다이어그램을 구성하게 됩니다.

그림 3. 상세 블록다이어그램

 

2. 함수팔레트에서 연결 » 라이브러리 & 실행파일 » 라이브러리 함수 호출 노드를 블록다이어그램에 넣습니다. 노드 상에는 단 한 세트의 터미널이 흐리게 나타나게 됩니다. 다음 단계에 따라서 이용하고자 하는 DLL기능을 라이브러리 함수 호출을 구성합니다.
 

a. 라이브러리 함수 호출 노드를 마우스 오른쪽 버튼으로 클릭하고 단축 메뉴에서 설정을 선택하여 라이브러리 함수 호출 노드 대화상자를 띄웁니다.


그림 4. 라이브러리 함수 호출 설정 화면


b. 탐색 버튼을 눌러 C:WINDOWS\system32 디렉터리에서 user32.dll을 선택합니다.
c. 함수 이름 풀다운 메뉴에서 MessageBoxA 기능을 선택하고 그 옆의 풀다운 메뉴에서 이 UI 스레드 안에서 실행을 선택합니다.
d. 호출 형식을 표준 호출(WINAPI)로 설정합니다. 이 후 파라미터 탭으로 이동합니다.


그림 5. 라이브러리 함수 호출 파라미터 설정 화면



e. MessageBoxA가 실행되어 나온 결과값은 32비트 정수로서 메시지 박스의 어떤 버튼이 눌러 졌는지를 나타내게 됩니다. 이것은 파라미터와 타입 필드에서 설정할 수 있습니다. 파라미터의 풀다운 메뉴에 return type으로 되어 있는지 확인하고 return type 매개변수의 이름을 ‘눌러진 버튼’과 같이 좀 더 설명적인 것으로 바꿉니다. 타입의 풀다운 메뉴에서 숫자형으로 설정하면 데이터 타입이 생기는데 데이터 타입의 풀다운 메뉴에서 32비트 부호 정수를 선택합니다.

다음은 MessageBoxA의 실행 시 필요한 네 개의 입력을 정의합니다.


그림 6. 기타 파라미터 설정_문자열 설정

f. MessageBoxA가 필요한 첫 번째 입력은 hWnd 매개변수로 이는 부호가 없는 32비트 정수입니다. 파라미터를 후에 추가 버튼을 누릅니다. 데이터 타입 메뉴에서 부호없는 32비트 정수를 선택합니다. 이 기능은 값을 가리키는 포인터가 아니라 값 자체를 예상하므로 전달 방법 설정을 값으로 되어있는지 확인 합니다. arg1의 매개변수 이름을 ‘hWnd’와 같이 좀 더 설명적인 것으로 바꿉니다.

g. 문자열을 두 번째 입력으로 매개변수 목록에 추가합니다. 첫 번째 입력이 파라미터 상자에 나타나는지 확인합니다. 파라미터 상자의 오른쪽에 있는 파라미터를 후에 추가 버튼을 클릭합니다. 데이터 유형을 문자열을 가리키는 포인터로 설정하려면, 타입 메뉴에서 문자열을 선택합니다. 기능에 문자열을 보낼 경우, 문자열을 가리키는 포인터가 C 유형의 문자열(뒤에 NULL 문자가 오는 문자열)을 가리킬지, Pascal 유형의 문자열(길이 바이트가 앞에 오는 문자열)을 가리킬지 아니면 LabVIEW 문자열 핸들(뒤에 문자열 데이터가 나오는 4바이트의 길이 정보)일지를 선택할 수 있습니다. 이 입력의 경우, 포멧 문자열을 C 문자열 포인터로 설정합니다. arg2의 매개변수 이름을 ‘메시지 내용'으로 바꿉니다.

h. 이 기능에 전달되는 세 번째 입력도 문자열 lpCaption으로, 여기에는 메시지 상자 창의 제목이 포함됩니다. g 단계를 반복하여 이 입력을 설정합니다. 이 입력의 이름은 ‘메시지 박스 제목’으로 합니다.

i. uType 매개변수를 추가합니다. 이는 네 번째 입력으로 부호가 없는 32비트 정수입니다. 이 값은 표시되는 메시지 상자의 유형을 결정합니다. 이 입력의 이름은 ‘메시지 박스 종류’로 합니다.

j. 라이브러리 함수 호출 노드 구성이 끝났으면 라이브러리 함수 호출 노드 대화상자에 표시되는 함수 원형과 위에서 한 MessageBoxA 기능 정보 단원에서 명시한 기능 설명서를 비교함으로써 이 구성을 확인합니다. 이렇게 하면 기능에 올바른 데이터 유형을 보내고 있는지 여부를 확인하는 데 도움이 됩니다. 아래의 예는 완성된 라이브러리 함수 호출 노드 대화상자입니다.


3. 확인 버튼을 클릭하여 라이브러리 함수 호출 노드 대화상자를 닫습니다. 라이브러리 함수 호출 노드에 터미널이 추가되어있고 이 함수 원형에서 왼쪽에서 오른쪽으로 나열되어있는 기능의 매개변수가 위에서 아래로의 노드 터미널에 나타나는 데이터 유형을 확인하실 수 있습니다. 맨 위에 있는 출력 단이 기능에 대한 입력이 아니라 기능의 반환 값이므로 왼쪽 상단의 입력은 사용할 수 없게 됩니다.
 

4. VI를 완성하려면, 이미 블록다이어그램에 있는 컨트롤과 인디케이터를 라이브러리 함수 호출 노드에 연결합니다. 
 
라이브러리 함수 호출 노드의 모든 입력 단에 데이터가 연결되어야 합니다. 


댓글