Меню сайта
Ваш профиль
Прохожий

Сообщения:

Группа:
Гости
Время:13:32

Гость, мы рады вас видеть. Пожалуйста зарегистрируйтесь или авторизуйтесь!
Последние темы
Чат
200
Статистика


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


Посетители за сегодня:
Главная » Статьи » Мои статьи

Добавление собственных Native функций Часть 1
Итак, обозначим порядок наших действий:

1. Написать нативку и скомпилировать dll
2. Добавить объявление написанной нативки в common.j
3. Написать код, использующий нативку
4. Запустить игру

Для начала возьмём классический пример "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")

Категория: Мои статьи | Добавил: Guard (25.07.2010)
Просмотров: 288 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Все права защищены 2025. Полное или частичное использование материалов сайта возможно только с ссылкой на источник.