יום רביעי, 12 בפברואר 2014

Managed / UnManaged Code




לאורך הבלוג נזרק המושג Managed Code מספר פעמים ולא יותר מידי הרחבתי עליו , אבל מסתתר מאחוריו פואנטה שכדאי להכיר ולכן החלטתי לכתוב מאמר קצרצר שיסביר את הנושא למרות שכבר עברתי עליו בצורה כזאת או אחרת בבלוג, החיבור בין 2 שיטות ריצה שונות מאפשר יצירת תוכניות מורכבות שמאפשרות ניצול של 2 פלטפורמות שונות זו מזו, לדוגמה האפשרות לכתוב שכבה שעובדת מול Win32 API שלא ניתן לגשת אליה באופן חופשי מ .Net כפי שכבר הראתי בעבר ב Personal Firewall.


Managed Code

סביבת .Net מוגדרת כ Manage Code ומזכירה בהתנהגות שלה את Java בכך שב 2 הסביבות נוצר חדר נקי שמאפשר לקוד לרוץ ללא הפרעות, במקרה של .Net אומנם נוצר קובץ EXE בסוף התהליך, אך כאשר מפעילים אותו הוא מפעיל מערכת שלמה מאחורי הקלעים על מנת שיוכל לרוץ, כאשר הקובץ נוצר, הוא נשמר בשפת בניים הנקראת IL ועובר למנגנון CLR ומשם ל JIT כפי שכתבתי במאמר Managed .Net RootKit, לכן זה לא באמת קוד מכונה, הוא נהפך לקוד מכונה תוך כדי ריצה.

UnManaged Code

זה קוד שנהפך לקוד מכונה ברגע שמבצעים את ה Compile ומאותו רגע הוא יכול לרוץ ולכן מהיר יותר, בדר"כ נכתוב אותו ב ++C/ C ונשתמש ב Compilers ותיקים בתחום, לא קיים חדר נקי ולכן התוכניות עלולות לגרום נזק למערכת הפעלה ישירות, בדרך כלל נשתמש בו כאשר נרצה לדבר ישירות עם ה Win32API או לשפר ביצועים, השפה שנהנת מכל העולמות היא ++C שמאפשרת כתיבת קוד משולב.

שימו לב! - ב Managed Code קיים מנגנון ה Garbage Collector שמשחרר זיכרון באופן עצמי גם אם לא שחררתם אותו בעצמכם לעומת זאת ב UnManaged Code הוא לא קיים ואחריות שחרור הזיכרון היא על המפתחים בלבד.

בדוגמה הבאה אני ידגים כיצד לחבר בין אפליקציית .Net עם פונקציות שנכתבו ב  ++C/ C, תחילה נתמקד ב UnManaged Code שאותו אני אכתוב ב ++C בעזרת Visual Studio.

dllctest.h

//in C++ we can have functions with the same name,
//the compiler create unique name for each function, 
//in C is not possible to have different functions with the same name, 
//the extern "C" tell the compiler to keep the name as is like in C
//be aware from functions with the same name!.
extern "C" {
//exported function signature,
//__declspec tell to compiler to expose the function
__declspec(dllexport)   char *  getString(void);
__declspec(dllexport)   void  setString(char * data);
}


dllctest.cpp

//dllctest.cpp : Defines the exported functions for the DLL application.
#include "stdafx.h"
#include "dllctest.h"

static char * sdata;

//tell to compiler someone else going to use this method
extern char * getString(void)
{
return sdata;
}

//tell to compiler someone else going to use this method
extern void setString(char * data)
{
sdata = data;
}

יש מספר מילים שמורות שאומרות ל Compiler שמדובר על פונקציות שמשהו אחר (חיצוני) הולך להשתמש בהם, ומאפשרות לחשוף אותן החוצה, בגלל שהקוד עצמו  ב ++C חשוב להגיד ל Compiler שישמור על השמות של הפונקציות כמו שהם בדומה להתנהגות של C כי אחרת הוא ממציא להן שמות בעצמו.

שימו לב! - חשוב מאוד שהשמות של הפונקציות לא יחזרו על עצמן, ב C זה בלתי אפשרי אבל ב ++C זה אפשרי ועלולה להיות התנגשות בין הפונקציות.

dllctestcs.cs

class Program
{
        //call to external function from dll 
        //using the same signature from the dll
        [DllImport(@"C:\inetpub\wwwroot\dllctest\Debug\dllctest.dll", CharSet = CharSet.Unicode)]
        extern static void setString(string data);

        [DllImport(@"C:\inetpub\wwwroot\dllctest\Debug\dllctest.dll",CharSet=CharSet.Unicode)]
        extern static string getString();

        static void Main(string[] args)
        {
            setString("HI");

            Console.Write(getString());

            Console.ReadLine();
        }
    }
על מנת לדבר עם ה DLL שיצרנו נשתמש ב (Platform Invocation Services (PInvoke , מנגנון שמגיע עם .Net שמאפשר לטעון DLL של UnManaged Code תוך כדי ריצה, במקרה שלנו אנחנו מעבירים מחרוזות לכן חשוב להגדיר את סוג הקידוד.

סיכום

תחשבו לכם איזה יתרון אדיר יש בשילוב בין 2 פלטפורמות שונות שמאפשרות לנו לגעת בכל העולמות, לצורך העניין ב .Net יש כלים נהדרים לעבודה על אתרי אינטרנט, בניית ממשקים, DB וכו' ואילו ב C נוכל לשפר ביצועים ולהגיע למקומות ש .Net לא יכול.

השילוב הראוי...

אין תגובות:

הוסף רשומת תגובה