2013/03/13

Windows DLL + Wine = Linux Program

Өнгөрсөн жил роботоор оффис цэвэрлүүлдэг төсөл дээр ажиллав. Тоос сорогч чирсэн (200 мянган евроны үнэтэй) хүн шиг том робот оффисийн өрөө болгоноор шагайгаад шал хаагуур халтар байгааг камер ашиглаж computer vision-ы тусламжтайгаар тогтооно. Хэдэн зуун өрөөтэй оффис цэвэрлэх тул цаг болон мөнгөө хэмнэж зөвхөн тэр халтар болсон хэсгийн л тоосыг нь сорно. Тоос сорсныхоо дараа цэвэрхэн болсон эсэхийг шалгана. Хэрвээ хэд хэдэн удаа тоос сорсон ч гэсэн цэвэрхэн болохгүй бол 3D scanner-аар тэр бохирдсон хэсгийг хэмжинэ. Энэ хэмжилтийнхээ тусламжтайгаар зүгээр будаг болсон толбо уу эсвэл бохь наалдсан овойж товойсон бохирдолт уу гэх мэтээр ангилаад мэдээллийн сан руу хийнэ. Сүүлд нь 7 хоногт нэг удаа ч юм уу цэвэрлэгч ирээд тэр мэдээллийн сан дээр хадгалагдсан арилдаггүй толбуудыг арилгана.

Надаа 3D scanner-аар хэмжилт хийх ажил нь оногдов. Цаанаас нь Shapescan3D хэмээх scanner өгөв. Зөвхөн Windows дээр ашиглаж болдог эд аж. API гээд нэг header файл болон DLL library дагаж ирсэн байлаа. Бид нар робот програмчлахдаа Robot Operating System (ROS) гэж middleware ашигладаг, тэр нь зөвхөн Ubuntu дээр л ажиллана. Тэгээд scanner-аа Ubuntu дээр хэрхэн ажиллуулах вэ гэж баахан толгойгоо гашилгав. IDA ашиглаж dissassemble хийж үзсэн болов ч туршлага дутаад олигтой амжилт олсонгүй. Wireshark ашиглаж scanner болон компьютер хоорондох communication-ийг чагнаж үзэв. Binary protocol ашиглаж байсан учир бас л сүртэй амжилт гаргасангүй.

Тэгээд аргаа бараад Wine ашиглахаар шийдэв. Урьд нь Wine ашиглаж Windows программ ажилуулж үзэж байснаас өөрөө программ бичиж DLL library дуудаж үзэж байгаагүй тул болох эсэхийг нь сайн мэдэхгүй байв. Scanner-дагаж A3DSensor.dll болон A3DSenshor.h гэж файлууд дагаж ирсний header нь иймэрхүү функцүүдтэй:


Энэ функцуудыг Wine ашиглаад Linux программаас дуудчихвал хамаг юм болчих гээд байлаа. Интернэтээс олсон энэ зааврын дагуу хийж үзэхээр шийдэв. Санасныг бодоход хялбар юм байна. DLL файлаа LoadLibrary method ашиглаж санах ойруу хуулаад GetProcAddress method-ын тусламжтайгаар дуудах гэж байгаа method-уудыхаа хаягийг олдог аж. DLL library-гаа ашиглаж дууссаныхаа дараа FreeLibray method ашиглаж санах ойноосоо буцааж устгана. Энэ гурван method гурвуулаа Windows-API.

Хамгийн түрүүнд DLL library-аа санах ойд ачааллана:


GetProcAddress method ашиглаж байгаа тул дагаж ирсэн header файлыг шууд ашиглаж болохгүй. Тиймээс бүх method-уудаа бага зэрэг өөрчлөөд дахиж шинээр зарлана. Жишээ нь


гэсэн method-ыг доорх байдлаар зарлана:


Дараа нь энэ method-ыхоо хаягийг олох хэрэгтэй:


Ингэснийхээ дараагаар method-уудаа яаг Windows дээр яаж ашиглах ёстой тэрэн шиг нь ашиглах боломжтой болно.

Программ бүтнээрээ:


Wine суулгахад wineg++, winegcc гээд compiler-ууд дагаж ирдэг. Энэ compiler-ыхаа тусламжтайгаар программаа build хийнэ:
wineg++ shapescan3d.cpp
Үүссэн программаа Linux дээр дуудхад ингэж гарч ирж байна:
$ ./a.out
Version: 2500

Яаг энэ аргаар бусад бүх method-уудаа зарлаад scanner-аа 100% Linux дээр ашиглаж болдог болгов. Wine ашигласны нэг сайн чанар нь бичиж байгаа программандаа Linux-API, Windows-API дураараа хольж болдог юм байна. Тэгээд бичсэн программ маань Linux программ гэхэд ч хэцүү Windows программ гэхэд ч хэцүү hybrid юм болвоо хөөрхий :)

6 comments:

  1. Wireshark-aar yaaj (holbolt tohirgoo ene ter) chagnaj uzsen be. Camera ni yamar interface tei yum bna. Bi oird Wireshark plugin tai neleen notsoldloo.

    Just FYI: Herev .LIB file dagaldaj irsen bol DLL implicit linking (as opposed to DLL explicit linking) hiihed arai amar, GetProcAddress duudah shaardlagagui baidag sanagdaj bna.

    ReplyDelete
  2. Camera ni ethernet interface tei. Tegeed ip aar ni sniff hiij uzsen yum.

    Bas zovhon *.dll bolon *.h file l dagaldaj irsen. Hervee *.lib file dagaldaj irsen bol herhen ashiglah talaar zaavar baina uu?

    ReplyDelete
  3. @Khash
    Windows deer program suusan folder iig ni shalgaj uzsen chin *.lib file baina :)

    ReplyDelete
  4. http://www.winehq.org/docs/winegcc

    The dllimport/dllexport attributes are not supported at the moment, due
    to lack of support for these features in the ELF version of gcc.

    Static linking is not currently supported against Wine's DLL. As a
    result, the -static, --static, and -Wl,-static options will generate an
    error.

    Genee. Tegeheer wine deer static linking (implicit linking) bolohgui yum shig bna. Windows deer DLL Implicit linking hiihed explicit linking ees barag yalgaagui. Header file dotor ni __declspec( dllimport ) modifier buhii funktsiin zarlagaanuud baih yostoi. Tegeed header file aa shuud *.c dotoroo #include hiigeed funktsuudee ashiglahad bolno. Harin link hiih uedee DLL ee bas zaaj ugnu.
    End neg yum bna.
    http://msdn.microsoft.com/en-us/library/d14wsce5(v=vs.80).aspx

    ReplyDelete
  5. Ойр ойрхон шинэ мэдээ нэмж байвал гоё л байна

    ReplyDelete
  6. AVR Butterfly нөгөө хүүхдэд аль дээр өгчихсөн, би өөртөө нэгийг авах гээд amazon ebay аас хайгаад байсан чинь олдохгүй юм оо, яаж захиж авах уу. Weniwe

    ReplyDelete