Пятница, 03.05.2024, 11:53


Главная
Регистрация
Вход
Dota Allstars ✪ World of WarCraft Приветствую Вас Гость | RSS  
Меню сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Главная » Статьи » Dota Allstars » Полезные статьи

Native функции: Часть 1: Порядок действий и простейший пример
Native функции: Часть 1: Порядок действий и простейший пример                   
 

Итак, обозначим порядок наших действий:
  • Написать нативку и скомпилировать dll
  • Добавить объявление написанной нативки в common.j
  • Написать код, использующий нативку
  • Запустить игру
Для начала возьмём классический пример "Hello world": напишем функцию, которая не принимает параметров, а возвращает некоторую строку. Вот наш test.cpp
#include <windows.h>
#include <stdio.h>

#define jNATIVE __stdcall
#define jAPI __cdecl

#define jString long
#define jInt long
#define jReal long

typedef void(jAPI *jpAddNative)(void *routine, char *name, char *prototype);
typedef jString(jAPI *jpStrMap)(const char *str);
typedef const char*(jAPI *jpStrGet)(jString strid);

jpAddNativejAddNative = NULL;
jpStrMapjStrMap = NULL;
jpStrGetjStrGet = NULL;

jString jNATIVE test()
{
 char *s = "ZOMG TEH FUNC!";
 return jStrMap(s);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
 if (ul_reason_for_call != DLL_PROCESS_ATTACH) return TRUE;
 DisableThreadLibraryCalls(hModule);

 HMODULE hjApi = GetModuleHandle("japi.dll");

 jAddNative = (jpAddNative)GetProcAddress(hjApi, "jAddNative");
 jStrMap= (jpStrMap)GetProcAddress(hjApi, "jStrMap");
 jStrGet= (jpStrGet)GetProcAddress(hjApi, "jStrGet");

 jAddNative((void *)test, "test", "()S");

 return TRUE;
}
Два важных места здесь - это:
jString jNATIVE test()
{
char *s = "ZOMG TEH FUNC!";

return jStrMap(s);

и
jAddNative((void *)test, "test", "()S");
Третий аргумент функции jAddNative определяет типы, передаваемые функции и возвращаемые ей.
Теперь скомпилируем DLL. Для этого в командной строке напишем
bcc32 -WD -e"test.dll" test.cpp
-WD значит компилировать dll, -e определяет выходной файл и test.cpp - соответственно наш файл с исходным текстом.
Следующим шагом нам необходимо добавить эту функцию в common.j (если у вас его нет, всегда можно достать последнюю версию из war3patch.mpq):
native test takes nothing returns string
Теперь создадим карту, в которой будет вызвана наша функция. Назовем её test.w3m и сохраним в папку Maps директории Warcraft. В карте создадим триггер Test, выполняющийся при инициализации и в действия добавим:
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,test())
Не забудьте импортировать в карту измененный common.j с путем "scripts\common.j", иначе при сохранении будет выдана ошибка.
Пришло время запускать игру. Распакуйте Grimoire в какую-то директорию неподалёку и приготовьтесь печатать. Открываем startwar3.bat, пишем и сохраняем:
bin\exehack.exe -s war3.lua -loadfile "Maps\test.w3m"
Теперь редактируем ongameload.lua, вот всё, что должно в нем остаться:
loaddll("bin\\japi.dll")
loaddll("bin\\test.dll")
Категория: Полезные статьи | Добавил: TRACTOR (27.05.2012)
Просмотров: 553 | Рейтинг: 0.0/0
Вход на сайт

Поиск

Copyright MyCorp © 2024Сделать бесплатный сайт с uCoz