AIMP Forum
AIMP for Windows => Дополнения / Addons => Разработка / Development => Topic started by: DarkDrawKill on March 29, 2025, 21:54:57
-
Решил научиться писать плагины на C++ для AIMP и в качестве начальной точки написал плагин, который ничего не делает. Ни документации, ни хендбука для C++ на просторах интернета нет. Пришлось ковырять код из забытых источников 10-х, которые используют ломаные враперы (wrapper), один из которых архивирован в 2021 году, а второй вообще не доступен (404 ошибка). Также задействовал новейшие технологии в сфере искусственного интеллекта в качестве помощника. Из его бредней я смог всё таки написать файл с плагином
MySuperPlugin.cpp
#include "apiPlugin.h"
#include "apiCore.h"
class MySuperPlugin: public IAIMPPlugin
{
ULONG refCount;
public:
MySuperPlugin() : refCount(0) {}
HRESULT WINAPI QueryInterface(REFIID riid, void** ppv) {
if (!ppv) return E_POINTER;
if (riid == IID_IUnknown) {
*ppv = this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
ULONG WINAPI AddRef() {
return InterlockedIncrement(&refCount);
}
ULONG WINAPI Release() {
ULONG count = InterlockedDecrement(&refCount);
if (count == 0) {
delete this;
}
return count;
}
TChar* WINAPI InfoGet(int index) {
return const_cast<TChar*>(L"MySuperPlugin");
}
HRESULT WINAPI Initialize(IAIMPCore *core) {
return S_OK;
}
HRESULT WINAPI Finalize() {
return S_OK;
}
LongWord WINAPI InfoGetCategories() {
return AIMP_PLUGIN_CATEGORY_ADDONS;
};
void WINAPI SystemNotification(int notifyID, IUnknown *Data) {}
};
HRESULT __declspec(dllexport) WINAPI AIMPPluginGetHeader(void **plugin) {
*plugin = new MySuperPlugin();
return S_OK;
}
Но про сборке и закидывании файла MySuperPlugin.dll его в AIMP\Plugins\MySuperPlugin AIMP его не видит. Я как угодно ковырял cmake, использовал MinGW, потом скачал Build Tools 2022 и использовал его, но он всё ни в какую не видит плагин.
CMakeLists.txt
cmake_minimum_required(VERSION 4.0.0)
project(MySuperPlugin)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED)
include_directories("lib/aimp_sdk/include")
add_library(${PROJECT_NAME} SHARED
"src/MySuperPlugin.cpp"
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
message(STATUS "Configuring for 64-bit")
else()
message(STATUS "Configuring for 32-bit")
endif()
set_target_properties(${PROJECT_NAME} PROPERTIES
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
Все заголовочные файлы я закинул в lib\aimp_sdk\include
-
Расширьте скомпилированный вариант плагина
-
HRESULT __declspec(dllexport) WINAPI AIMPPluginGetHeader(void **plugin) {
*plugin = new MySuperPlugin();
return S_OK;
}
Не знаю, как в mingw, в студии нужно указать список функций для экспорта через def. Убедитесь, что эта функция таки присутствует в секции экспорта
плагин, который ничего не делает. Ни документации, ни хендбука для C++ на просторах интернета нет
По плагинам на C++ для аимп? плагины - обычные dll-ки. В качестве примера можно посмотреть вот на этот: https://github.com/ArtemIzmaylov/aimp_vgmstream/tree/main/aimp_vgmstream
-
в студии нужно указать список функций для экспорта через def
Я не использую студио. У меня стоит vscode + cmake с build tools.
Я сделал файл MySuperPlugin.def
LIBRARY "MySuperPlugin"
EXPORTS
AIMPPluginGetHeader
А также добавил строчки в CMakeLists.txt
add_library(${PROJECT_NAME} SHARED
"src/MySuperPlugin.cpp"
"src/MySuperPlugin.def"
)
set_source_files_properties("src/MySuperPlugin.def" EXPORT_PROPERTIES)
При загрузке AIMP наконец-то увидел плагин, но добавил его в неиспользуемые. Видимо это из-за того что он просто ничего не делает
-
но добавил его в неиспользуемые
Туда плагины попадают, если Initialize вернул не 0
-
Туда плагины попадают, если Initialize вернул не 0
Да, я просто забыл что переписывал метод Initialize, видимо он возвращает E_ABORT из-за того что что-то идёт не так
HRESULT WINAPI Initialize(IAIMPCore *core) {
IAIMPString** testString = nullptr;
if (SUCCEEDED(core->CreateObject(IID_IAIMPString, (void**)testString))) {
TChar helloWorldText[] = L"Hello world!";
(*testString)->SetData(helloWorldText, wcslen(helloWorldText));
IAIMPServiceMessageDispatcher **messageService = nullptr;
if (SUCCEEDED(core->QueryInterface(IID_IAIMPServiceMessageDispatcher, (void**)messageService))) {
HWND aimpHwnd = NULL;
(*messageService)->Send(AIMP_MSG_PROPERTY_HWND, AIMP_MSG_PROPVALUE_GET, &aimpHwnd);
MessageBoxW(
aimpHwnd,
(*testString)->GetData(),
L"AIMP",
MB_OK
);
(*testString)->Release();
return S_OK;
}
}
return E_ABORT;
}
Upd: этот код был сгенерирован нейросетью
-
Да, я просто забыл что переписывал метод Initialize, видимо он возвращает E_ABORT из-за того что что-то идёт не так
HRESULT WINAPI Initialize(IAIMPCore *core) {
IAIMPString** testString = nullptr;
if (SUCCEEDED(core->CreateObject(IID_IAIMPString, (void**)testString))) {
TChar helloWorldText[] = L"Hello world!";
(*testString)->SetData(helloWorldText, wcslen(helloWorldText));
IAIMPServiceMessageDispatcher **messageService = nullptr;
if (SUCCEEDED(core->QueryInterface(IID_IAIMPServiceMessageDispatcher, (void**)messageService))) {
HWND aimpHwnd = NULL;
(*messageService)->Send(AIMP_MSG_PROPERTY_HWND, AIMP_MSG_PROPVALUE_GET, &aimpHwnd);
MessageBoxW(
aimpHwnd,
(*testString)->GetData(),
L"AIMP",
MB_OK
);
(*testString)->Release();
return S_OK;
}
}
return E_ABORT;
}
на будущее: для построения UI старайтесь использовать возможности apiGUI заместо стандартных виндовых
-
Попробовал переключиться на mingw и он начинает жаловаться на функцию экспорта. Я погуглил и там def файл загружается по другому и более костыльным способом. Пока не разберусь в чём проблема я буду использовать build tools
-
для построения UI старайтесь использовать возможности apiGUI заместо стандартных виндовых
Когда я написал "hello world" через apiGUI, заметил что в sdk 540 в ahiGUI.h в 1166 строке стоит { IAIMPUIAuthDialog }
-
Когда я написал "hello world" через apiGUI, заметил что в sdk 540 в ahiGUI.h в 1166 строке стоит
проверил, в актуальном SDK все корректно.
-
проверил, в актуальном SDK все корректно.
У меня видимо билд 2650