삽질하는플머

모노 2.10 설치. MySql 연결 테스트.

여가생활/Unity,Mono&.Net

시작은 유니티였는데... 옆길로 참 많이 새고 있다. 


굳이 이런 시도를 해보는 이유는? 모노가 WCF를 지원하고 있다는 것에 눈이 번쩍 띄었기 때문이다. 

현재 XMLRPC+PHP로 DB를 호출하고, 이 PHP를 HipHop으로 빌드해 바이너리로 서비스하는 방식을 쓰는 중인데...

닷넷으로 WCF 서비스를 만들고 델파이로 접근해 사용하도록 바꿔준다면 손도 편하고 머리속도 간단해지니까. 

게다가 C#은 디버깅도 되잖아? 디버거 없이 날코딩하는 PHP같은 인터프리터 언어는 나이가 먹을수록 부담스러워~~


기왕에 삽질할 꺼면 모노 2.8 이상을 설치해 새 바닥에서 놀자. 


우분투에 모노 2.10 설치는 트위터의 @nbridgewater 님이 작성한 스크립트를 쓰면 한방에 해결. 

중간 중간에 sudo 암호만 넣어주면 된다. 시간은 좀 오래 걸림. 


http://www.integratedwebsystems.com/2011/02/mono-2-10-install-script-for-ubuntu-fedora/


# wget --no-check-certificate https://github.com/nathanb/iws-snippets/raw/master/mono-install-scripts/ubuntu/install_mono-2.10.sh

# chmod 755 install_mono-2.10.sh

# ./install_mono-2.10.sh



위치는 /opt/mono-2.10 에 설치된다. 다음과 같이 윈도에서 #Develop 로 작성한 .Net 4.0 바이너리를 실행시킬 수 있다. 


# /opt/mono-2.10/bin/mono ./test.exe

Hello World!

#



MySql의 닷넷용 커넥터는 MySQL 에서 직접 개발 및 배포하고 있다. 라이센스는 GPL. 

http://dev.mysql.com/downloads/connector/net/


현재 버전은 6.5.4 이다. 일단 윈도용을 내려받아 설치하자. 







#Develop 에서 mysql-test 솔루션을 시작한다. 프로젝트 탐색기의 "참조" 에서 우측키를 누른 뒤 "참조 추가" 메뉴를 클릭하자. 

GAC 탭에서 "MySql.Data" 를 선택한 뒤 "확인"을 눌러준다. 




http://www.mono-project.com/MySQL 에 MySql 에 접근하는 좋은 예제가 있다. 

int형 ID와 varchar형 Name 을 필드로 가지는 테스트용 DB에 접근하는 코드를 다음과 같이 만들어주었다. 


using System;
using System.Data;
using MySql.Data.MySqlClient;

namespace mysql_test
{
    class Program
    {
        public static void Main(string[] args)
        {
            string connectionString =     
              "Server=hostname;" +
              "Database=test;" +
              "User ID=user;" +
              "Password=password;" +
              "Pooling=false";
            
            IDbConnection dbcon;
            dbcon = new MySqlConnection(connectionString);
            dbcon.Open();
            IDbCommand dbcmd = dbcon.CreateCommand();
            
            string sql =
               "SELECT ID, Name " +
               "FROM test";
            
            dbcmd.CommandText = sql;
            IDataReader reader = dbcmd.ExecuteReader();
            while(reader.Read()) {
                int ID = (int) reader["ID"];
                string Name = (string) reader["test"];
                Console.WriteLine("Data: " + ID + " " + Name);
            }
            // clean up
            reader.Close();
            reader = null;
            dbcmd.Dispose();
            dbcmd = null;
            dbcon.Close();
            dbcon = null;

            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
    }
}

(#Develop 에서 코드를 복사해 블로그에 붙여넣으면 하이라이팅이 그대로 살아있네~ 좋다!!)



실행시켜보면 자알~ 동작한다. 





이제 모노의 GAC에 MySql 라이브러리를 설치해보자. http://dev.mysql.com/downloads/connector/net/ 에서 ".Net & Mono" 를 선택한 뒤 "mysql-connector-net-6.5.4-noinstall.zip" 파일을 다운받아 압축을 푼다. 이 압축파일에 포함된 dll은 모두 소문자로 되어있지만 GAC에 등록하기 위해서는 실제 C#에서 참조할 때와 동일하게 대소문자를 맞춰주어야 한다는 것에 주의!


# cd mysql-connector-net-6.5.4-noinstall/

# cd v2

# cp mysql.data.dll MySql.Data.dll

# sudo /opt/mono-2.10/bin/gacutil -i MySql.Data.dll
 Installed MySql.Data.dll into the gac (/opt/mono-2.10/lib/mono/gac)


윈도에서 작성된 바이너리를 옮겨와 다음과 같이 실행시켜보자. 


/opt/mono-2.10/bin/mono ./mysql-test.exe



결과는 짜잔~




덤으로, 앞에서 작성한 CS 코드를 우분투에서 직접 빌드하려면 다음과 같이 하면 된다. 

/opt/mono-2.10/bin/mcs mysql-test.cs  -r:System.Data.dll -r:/opt/mono-2.10/lib/mono/gac/MySql.Data/6.5.4.0__c5687fc88969c44d/MySql.Data.dll


당연한 이야기지만, 이렇게 빌드한 실행파일도 윈도에서 잘 돌아간다. 



크로스 플랫폼으로서의 모노...

여가생활/Unity,Mono&.Net
유니티 얘기하다가 왜 뜬금없이 모노냐고? 취미는 중간에 샛길로 빠지는 맛에 즐기는 거거덩.

오래전 셀빅이라는 물건이 대한민국 PDA의 대명사이던 시절, 
도스나 윈도 이외의 플랫폼이 주는 상큼 발랄했던 청량감은 내게 오랫동안 잊기 힘든 깊은 자욱을 남겼고
그때문인지 발은 윈도에 묶여있으면서도 마음은 항상 다른 플랫폼을 지향하며 살게 된 듯 하다. 

시스템 잡동사니 -> 게임클라이언트 -> 게임서버 프로그래머의 삶을 살아가는 입장에서 
네이티브 바이너리가 아닌 자바나 닷넷은 쉽게 경험하기 힘든 영역이었다. 
그러다보니 머리가 꽉꽉 막혀버려서 뻘생각과 잡짓을 삶의 낙으로 삼으면서도 보수적인 생각에서 한치도 벗어나지 못했는데
유니티 덕분에 모노디벨롭과  SharpDevelop(귀찮으니 앞으로는 #Develop 이라고 쓰자) 을 설치하고
초보수준이지만 C#을 건드리면서 저절로 튀어나온 탄성!!
야~! 이거 신세상이네~~!! 

어쩌면 모노는 내가 그리도 찾아 해메던 크로스 플랫폼에 대한 종착점이 아닐까 하는 생각까지...
거기에 모노 2.6 부터는 LLVM도 지원하지.
LLVM 의 자바스크립트 백엔드인 emscripten 의 강력함을 생각하면
네이티브 바이너리에 대한 집착을 버려야 할 시점이 생각보다 빨리 올지도 모르겠다. 

아무튼 똥인지 된장인지 알려면 일단 찍어먹어 봐야지.

테스트용으로 구동중인 우분투 10.04 서버에 모노를 설치하자. 
2.8을 설치하면 .Net 4.0 도 지원한다고 하지만... 뭐 나중에 병렬 프레임웍을 사용할 때나 해보고~
나와라~ apt-get~~!!!

sudo apt-get install mono-1.0-gac mono-2.0-gac



이제 #Develop 에서 C#으로 콘솔 응용 프로그램을 하나 만들자. 



모노 1.0과 2.0을 깔았으니 .NET Framework는 4.0이 아닌 3.5!!! 로 설정한다. 

자동으로 만들어지는 Hello World 밑에 한글이 UTF-8 로 잘 빠지는지도 확인할 겸 적절한 메시지를 하나 더 출력하자. 

using System;

namespace console_test
{
    class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Console.WriteLine("우하하하!!");
            
            Console.Write("Press any key to continue . . .\n");
            Console.ReadKey(true);
        }
    }
}


 
윈도에서 실행시킨 화면은 



생성된 console.exe 파일을 리눅스로 옮겨서 돌려보면




정말 세상 좋아졌네.


은양의 프로그래밍 세상에서 C# 서버 코드를 참고, 전송된 바이트값을 바로 리턴하는 간단한 에코서버를 만들었다. 
우분투로 옮기고 실행시킨 뒤 텔넷으로 접속해보니 아주 잘 동작한다. 



이거 짭짤한데~??


내친김에 가상머신에 코분투 10.04 를 설치했다.
데스크탑 폰트는 나눔고딕으로 맞춰주었고 mono-2.0-gac 가 이미 깔려있는 상태. 
여기에 윈폼을 돌리려면  mono-winforms 패키지를 추가로 설치해주어야 한다. 

sudo apt-get install mono-winforms-a11y 




#Develop 에서 간단한 윈폼기반의 실행파일을 하나 만들어 본다. 

 

이 실행파일을 방금 설치한 따끈따끈한 코분투로 이동시킨 뒤 돌려보자. 두근두근~~



첫술에 배부를까마는... 폼 타이틀을 제외한 나머지 글자들이 모두 깨져버린다. 
실망감은 잠시 미루고, 찬찬히 뜯어보면 네모로 표시된 글자의 갯수가 윈도에서 찍으려던 한글의 갯수와 동일하다.  
즉 이것은 유니스크라이브 때도 지겹게 겪었던 폰트문제...

코분투에서 윈폼에 인식된 기본폰트와  다이얼로그 폰트를 다음 코드로 찍어보았다. 

            MessageBox.Show(SystemFonts.DefaultFont.Name);
            MessageBox.Show(SystemFonts.DialogFont.Name);



결과는 "DejaVu sans".
영문폰트라 한글이 없으니 네모로 치환된 것이겠지. 폰트 폴백도 자동으로 되면 좋겠지만... 흠냐리... 

다행히 예전에 링크해 둔 우분투 글꼴 설정에 대한 블로그가 떠올랐다. 
http://anothertimes.tistory.com/22
 

/etc/fonts/conf.d/69-language-selector-ko-kr.conf 에서 sans 구성의 DejaVu Sans 를 아예 날려버리고 나눔고딕만 남겨두자. 

                 <edit name="family" mode="prepend" binding="strong">

                        <string>DejaVu Sans</string> // 이 라인 삭제
                        <string>NanumGothic</string>
                </edit>



재부팅 후 다시 돌려보면 짜잔~~

 

글자 크기가 조금 작은게 불만이네~ 이건 다음에 심심할 때 또 다뤄보자~~

 

유니티 테스트 2 - 회전댐퍼

여가생활/Unity,Mono&.Net
뭐 지인들이 이 글을 보면... 왜 이 인간이 이 짓거리를 하는지 대충 파악할 듯... ^^;
아무튼 어제에 이어 회전댐퍼도 만들어 보았다. SharpDevelop 라는 툴을 만난 덕분에 코딩속도는 *3 이상 증가. 

이건 뭐 쿼터니온 관련 함수들도 모두 내장되어있으니 그냥 가져다 쓰기만 하면 되네~ 완전 행복한 놀이터~~!!



유니티 만세!!


 

유니티 테스트 1 - 위치댐퍼

여가생활/Unity,Mono&.Net
유니티에 익숙해져볼 요량으로, 델파이로 만들었던 가감속 댐퍼 객체를 C#으로 바꿔 이식해보았다. 
이번 3.5 버전부터 프리뷰로 들어간 플래시 출력을 한 번 걸어봤는데... 아주 아주 잘 되는군. 
가끔씩 튀는 경우도 있기는 한데... 초벌변환한 코드가 그렇지 뭐. 몇 번 손보면 안정화될 듯. 



유니티는 뭔가 눈으로 보면서 확인하며 코딩하는데 익숙한 내게, 귀찮은 3D 코딩을 털어버리고 알맹이에만 집중할 수 있는 환경을 제공한다. 
오래 전 도스에서 윈도로 넘어가던 시절, 윈도 하나 띄우려고 주절주절 읊어주어야 하는 API 목록에 질려 비베를 깔짝이다가 델파이를 만났을 때의 감동이 느껴진다.  게다가 처음 써 본 C#은 델파이와 마치 형제처럼 닮아있다. 

아직 익숙치 않지만 조금씩 친해지는 느낌이 좋다. 손에 익으면 정말 쓰기 편한 물건이 될 듯 하다. 
 

Unity 3D 설치. MonoDevelop 와의 첫 만남.

여가생활/Unity,Mono&.Net
Unity 3D 는 알게 모르게 어느새 대세가 되어있는 무시하기 힘든 멋진 물건. 
4월 8일까지 iOS, 안드로이드 빌드가 가능한 Basic 버전을 무료로 배포하는 통 큰 행사덕에 일단 다운받아 깔아보았다.
말로만 듣던 MonoDevelop 도 한번쯤 써보고 싶었고...

유니티와 함께 설치된 MonoDevelop 는 유니티용으로 필요한 것만 추린 물건이라 많은 부분이 비어있다.
윈도나 하나 띄워볼까 싶어 GTK 프로젝트를 생성하니 에러만 빠바방~  심지어는 디버거도 없다.  

일단 GTK# 부터 설치해보자. 
http://monodevelop.com/Download 

여기서 윈도 아이콘을 눌러주면  "GTK# for .NET 2.12.10" 을 내려받을 수 있는 링크가 나타난다. 




설치한 후 생성된 .NET 바이너리를 실행시키려면 GTK# 이 설치된 디렉토리에 PATH가 걸려있어야 한다. 
바로 적용되지 않으니 시스템->등록정보에서 환경변수를 한 번 확인해주거나 귀찮으면 그냥 재부팅 하자.

이제 MonoDevelop 에서 GTK# 프로젝트를 생성하고 GUI Designer 를 사용할 수 있다. 








유니티용 MonoDevelop는 유니티용으로 이런저런 설정이 추가된 물건이라 그런지 디버거도 빠져있다. 
어차피 유니티용이고 스크립트 작업시 디버거로 유니티 자체를 실행시키도록 되어있으니 빼버린 듯 하다. 
뭐 정 필요하면 독립적인 MonoDevelop을 내려받아 쓰면 될 일이고... 어차피 C#을 다른 곳에 쓸 일은 없으니 일단 패스. 
다만 일반적인 어플을 만들때와 달리 유니티에서 띄우면 Run 메뉴가 비활성화되고 Debug 메뉴만 살아있는 게 신기하군. 
유니티 프로젝트를 불러왔을 때 Reference 에 UnityEngine.dll 이 포함되어있는 것과 관련이 있는 듯. 



실제로 그런지 파보자. Hello World를 출력해주는 빈 콘솔 프로젝트를 시작하고 컴파일. 이 시점에서 Run 메뉴는 아직 살아있다. 




솔루션 브라우저에서 "References" 를 우클릭하고 "Edit Preferences" 메뉴를 선택한 뒤 ".Net Assemply" 탭에서 유니티가 설치된 디렉토리 아래 .../Editor/Data/Managed/ 폴더로 이동, UnityEngine.dll 을 선택한 뒤 Add버튼을 눌러준다. 



이 DLL을 포함시키는 순간, MonoDevelop의 Run 메뉴는 비활성화되고 Debug 메뉴가 활성화된다. 
UnityEngine 네임스페이스에 접근할 수 있으므로 UnityEngine의 자료형을 테스트 해볼 수도 있다. 

.....

UnityEngine.Vector3 vt = UnityEngine.Vector3.left;
Console.WriteLine ("{0}, {1}, {2}", vt.x, vt.y, vt.z);

...... 


실행버튼이 비활성화되어있으니 Ctrl+F8로 빌드하고 생성된 실행파일을 탐색기에서 직접 돌려보자. 



오호~~ 뭔가 감이 잡히는 듯 해~~

당연한 얘기겠지만, 이렇게 만들어진 실행파일은 유니티 프로젝트가 아니므로 실제 뭔가를 하는 것은 불가능하다.
틱을 얻기 위해 여기저기 찔러서 알아낸 다음과 같은 코드도 빌드는 되지만 실행시키면 에러가 난다. 

......
float f = UnityEngine.Time.realtimeSinceStartup;
Console.WriteLine(f);



그래도 유니티와 모노가 이렇게 연결되어 동작하는구나~~ 짐작하게 되었으니 이것만으로도 큰 수확!

 



실제로 간단한 코드를 만들어 디버깅을 걸어보자. 
델파이를 오래 쓰다보니 뭔가 하려면 무조건 GUI가 있어줘야 하는 부작용이 있네. 
기왕 이렇게 된 거, 유니티의 GUI 요소들을 직접 가지고 놀아보자. 

GUI 스크립팅에 대한 레퍼런스 메뉴얼은 여기 .
http://unity3d.com/support/documentation/Components/GUI%20Scripting%20Guide.html 

유니티 강좌는 여기저기 많이 있으니 자세한 설명은 패스. 
유니티를 실행하고 빈 프로젝트를 생성하고 프로젝트 창에서 우클릭, GuiTest 라는 C#스크립트를 생성하자.
이 스크립트를 더블클릭하면 MonoDevelop가 실행된다. 여기에 다음과 같이 코딩해준다. 

using UnityEngine;
using System.Collections;

public class GuiTest : MonoBehaviour {

void OnGUI () {
if (GUI.Button (new Rect (10,10,150,100), "I am a button")) {
float f = Time.realtimeSinceStartup;
print ("Time from Start: " + f);
}
}
}





이 녀석을 끌어다 Hierachy 에 외롭게 혼자 있는 MainCamera 에 던져넣자. 



 
"Main Camera" 를 선택하고 Inspector 를 살펴보면 방금 추가한 GuiTest가 아래쪽에 보인다. 

 

Ctrl+Shift+C 를 눌러 콘솔을 띄운 뒤 유니티 상단의 실행 아이콘을 눌러주자. 
Game창에 버튼이 하나 생겨나고 이 버튼을 누를 때 마다 콘솔창에 이 게임이 실행된 후 경과된 시간값이 초단위로 출력된다. 


 
이제 실제로 디버깅을 걸어보자. 유니티를 닫고 모노만 남겨둔다.

모노에서 Run->Debug 메뉴를 선택하면 유니티가 다시 실행되면서 디버깅이 연결된다. 
아까 스크립트의 실행을 연결해두었던 MainCamera 가 어찌된 일인지 사라져버렸다. 
뭐 GameObject->CreateOther->Camera를 선택해 다시 만들자. 
새로 추가한 Camera에 아까와 같은 요령으로 GuiTest 스크립트를 연결해주고 실행아이콘을 누른다. 
모노에서 Print (...) 부분에 F9키로 브레이크 포인트를 걸고 유니티의 게임창에서 Gui버튼을 눌러보자. 

 

 

게임 실행이 브레이크 포인트에서 멈춘다. GUI버튼도 눌린 상태로 멈춰있다. 
당연히 Watch도 잘 동작한다. Step Over 로 한줄씩 지나가며 상태가 궁금한 변수는 들여다 볼 수 있다.
함수가 있다면 Step Into, Step Out 으로 들락날락 할 수도 있다. 이정도면 뭐~~ 쓸만하다. 

하지만... 디버깅이 길어질 수록 유니티가 더럽게 느려진다는 게 문제. 그리고 디버깅을 하려면 유니티를 다시 띄워야 하는 것도 불만.
기존 작업중인 상태에서 직접 디버거를 연결할 수 있다면 자주 쓰겠는데... 이 부분은 좀 더 뒤져봐야겠다. 


덤.
느려지는 문제가 집에 컴터가 꾸져서 그런가 싶었는데... 회사에서 재연해보니 마찬가지임. 

 
 덤 2. 
아직 유니티 문서 보는데 익숙치 않아서 해메게 되네. 암튼 찾아보니 디버깅에 대해 잘 정리된 문서가 있다. 
http://unity3d.com/support/documentation/Manual/Debugger.html 

Assets -> "Sync ModeDevelop Project" 메뉴를 한 번 실행시킨다. 
모노에서 Run -> Attack to Process... 메뉴를 선택한 뒤 실행중인 유니티 프로세스를 골라주면 끝!!
이 방법은 개발버전으로 빌드된 결과물들을 디버깅 할 때도 동일하다.