Windows용 PHP Extension을 Visual C++ 2008 Express Edition으로 만드는 법.
http://www.talkphp.com/vbarticles.php?do=article&articleid=49&title=creating-custom-php-extensions
준비물 (PHP 버전은 5.2.X 를 기준으로 함)
- 설치된 PHP : XAMPP-1.7.1
- PHP 소스 : PHP-5.2.13-src.zip
- Microsoft Visual C++ 2008 : http://www.microsoft.com/express/downloads
1. Visual C++ 2008 세팅
1-1. 프로젝트 생성
- Visual C++ 2008을 실행하고 새 프로젝트를 생성
- File > New > Project를 선택하고 New Project 창에서 Project types=Win32, Templates=Win32 Project를 선택하고, Name, Location, Solution Name은 알아서 입력 후 OK
- 다음에 나타나는 창에서 좌측의 Application Settings를 선택하고, Application type은 DLL을 선택한 후 Finish 클릭. 프로젝트 생성 완료.
1-2. PHP Extension 컴파일을 위한 환경설정
- Solution Explorer창에서 우클릭하고 Properties 선택.
[Include 경로 추가]
Configuration Properties > C/C++ > General에서 Additional Include Directories를 선택하고 우측버튼 클릭.
Additional Include Directories 창에서 각 라인을 더블클릭하여 아래 그림처럼 세팅.
!! C:\PHP_Source 폴더는 설치된 PHP가 아니라 PHP 소스파일이 있는 경로임 !!
[전처리기 추가]
Configuration Properties > C/C++ > Preprocessor 에서 Preprocessor Definitions를 선택하고 우측버튼 클릭.
Preprocessor Definitions 창에서 아래 그림처럼 4라인을 추가
[추가 라이브러리 경로 지정]
Configuration Properties > Linker > General 에서 Additional Library Directories를 선택하고 우측버튼을 클릭
Additional Library Directories 창에서 아래 그림처럼 설치된 PHP의 dev 경로를 추가.
(해당 경로에는 php5ts.lib 파일이 있음)
!! C:\xampp\php 는 설치된 PHP 경로임 !!
[라이브러리 파일 지정]
Configuration Properties > Linker > Input 에서 Additional Dependencies를 선택하고 우측버튼 클릭
Additional Dependencies 창에서 아래 그림처럼 php5ts.lib 를 입력하고 OK 클릭.
[커맨드라인 지정]
Configuration Properties > Linker > Command Line 의 Additional options에 /FORCE:MULTIPLE 추가
[DLL 파일명 지정]
PHP Extension은 php_EXTNAME.dll 의 규약(-_-)을 가지므로 생성될 DLL 파일의 이름을 지정.
Configuration Properties > Linker > General 의 Output File 부분을 아래 그림처럼 원하는 DLL 이름으로 변경.
2. 소스파일 세팅
2-1. standard header 수정
stdafx.h 파일을 열어서 아래처럼 수정 후 저장.
#pragma once
#include "zend_config.w32.h"
#include "php.h"
#include "zend_config.w32.h"
#include "php.h"
2-2. zend_config.w32.h 수정
#include "zend_config.w32.h" 부분에서 우클릭하여 'Open document'를 선택하거나,
C:\PHP_Source\Zend\zend_config.w32.h 파일을 직접 열어 아래처럼 수정.
51라인의 vsnprintf define 부분을 주석처리하거나 삭제하면 됨.
그리고 저장.
!! C:\PHP_Soruce 는 PHP 소스파일 경로임 !!
3. PHP Extension 제작
boolean을 매개변수로 받아서 true 이면 "True"를, false이면 "False"를 반환하는 my_func이라는 함수를 만들어 봄.
MyTest.cpp 파일을 아래처럼 코딩.
#include "stdafx.h"
ZEND_FUNCTION(my_func);
zend_function_entry my_test_function[] = {
ZEND_FE(my_func, NULL)
{NULL, NULL, NULL}
};
zend_module_entry my_test_module_entry = {
STANDARD_MODULE_HEADER,
"MyTest Extension",
my_test_function,
NULL, NULL, NULL, NULL, NULL,
"1.0",
STANDARD_MODULE_PROPERTIES
};
ZEND_GET_MODULE(my_test);
ZEND_FUNCTION(my_func)
{
bool my_bool = false;
char* result = "";
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &my_bool) == FAILURE) {
RETURN_STRING("Missing Parameter", true);
}
if (my_bool == true) result = "True";
else result = "False";
RETURN_STRING(result, true);
}
ZEND_FUNCTION(my_func);
zend_function_entry my_test_function[] = {
ZEND_FE(my_func, NULL)
{NULL, NULL, NULL}
};
zend_module_entry my_test_module_entry = {
STANDARD_MODULE_HEADER,
"MyTest Extension",
my_test_function,
NULL, NULL, NULL, NULL, NULL,
"1.0",
STANDARD_MODULE_PROPERTIES
};
ZEND_GET_MODULE(my_test);
ZEND_FUNCTION(my_func)
{
bool my_bool = false;
char* result = "";
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &my_bool) == FAILURE) {
RETURN_STRING("Missing Parameter", true);
}
if (my_bool == true) result = "True";
else result = "False";
RETURN_STRING(result, true);
}
F7을 누르거나 해서 프로젝트를 빌드함.
warning이 엄청나게 뜨지만 error는 없이, 여하튼 컴파일은 성공.
C:\PHP_Extension\MyTest\Debug 폴더에 가서 php_mytest.dll 파일이 있는지 확인.
!! C:\PHP_Extension은 DLL 프로젝트 경로임 !!
4. PHP Extension 로딩
4-1. DLL 복사
생성된 dll 파일을 PHP의 Extension 폴더로 복사.
C:\xampp\php\ext 폴더에 php_mytest.dll 을 복사.
4-2. php.ini
php.ini 파일을 열어 아래처럼 한 줄을 추가
4-3. apache 재시작
4-4. phpinfo 확인
phpinfo() 정보를 출력하여 Additional Modules에 MyTest Extension이 있는지 확인
4-5. PHP 테스트
PHP 파일에서 my_func() 함수를 테스트.
아래처럼 소스파일을 작성하고 브라우저로 확인.
<?php
$temp = 'my_func(<b>%s</b>) returns <b>%s</b><br/>';
printf($temp, 'true', my_func(true));
printf($temp, 'false', my_func(false));
printf($temp, '', my_func());
printf($temp, '0', my_func(0));
printf($temp, '1', my_func(1));
?>
$temp = 'my_func(<b>%s</b>) returns <b>%s</b><br/>';
printf($temp, 'true', my_func(true));
printf($temp, 'false', my_func(false));
printf($temp, '', my_func());
printf($temp, '0', my_func(0));
printf($temp, '1', my_func(1));
?>
다음과 같은 결과가 나오면 성공.
'PHP' 카테고리의 다른 글
[PHP Extension] Apache 2.2 + PHP 5.2 + PHP Extension (Linux) (0) | 2010.07.27 |
---|---|
[PHP Extension] PHP Extension Debugging (Visual C++ 2008) (0) | 2010.07.19 |
[PHP] 원본 문자열에서 특정 문자열의 위치를 모두 추출하여 반환 (0) | 2010.07.14 |
[PHP] SpreadSheet_Excel_Reader 64비트 CPU 오류. (0) | 2010.06.15 |
[PHP] UTF-8 BOM 떼어 내기 (0) | 2010.05.24 |