Hello World plugin

Started by Kara Jo Kalinowski, Tue 18/02/2025 03:09:44

Previous topic - Next topic

Kara Jo Kalinowski

I have Visual Studio installed with MSVC as the help file says we should be using. I can't wrap my head around how to make a .dll file for runtime stuff. ChatGPT seemed to think I needed to download agsplugin.h but I didn't need the other files in the engine/plugins folder, but you can't really trust what ChatGPT says.

I did a new project / DLL

I'm trying various things, but it's complaining about things. Is there something simple that you could show me just to understand how it's meant to work? (I have never done anything with DLL files specifically.)

Specifically, I'm just messing around - I don't have a goal in mind other than wanting to add functionality when AGS's code seems limited, and just to know how they work. I am trying to make a run-time engine plugin as the first thing.

Crimson Wizard

Yes, you need only agsplugin.h, and you don't need any other files. agsplugin.h contains declaration of the engine's API. The latest one may be found here:
https://github.com/adventuregamestudio/ags/blob/master/Engine/plugin/agsplugin.h

I wish we had a template project for the plugin, but we still don't. I might make one later in a separate repository.

You may check out one of the existing plugins, for example here's my "sprite video" plugin:
https://github.com/ivan-mogilko/ags-spritevideo
although it may be overcomplicated for an example.
The minimal necessary files are:
agsplugin.h
ags_spritevideo.cpp - contains standard plugin callbacks (AGS_EngineStartup, AGS_EngineShutdown, etc) and DLLMain for Windows DLL
EditorPlugin.cpp - contains callbacks for the Editor, which generate plugin's script header (necessary for scripts to compile).

You may organize your plugin differently. It does not matter which *files* are there in the project, but rather which standard callbacks are included in those files, because that's what editor and engine will be looking for.

Kara Jo Kalinowski

Trying to learn from huge projects without explanations overwhelms me, but I'll try. I don't quite understand the bare minimum that needs to be included in a plugin for it to work.

Crimson Wizard

#3
Quote from: Kara Jo Kalinowski on Tue 18/02/2025 04:53:04Trying to learn from huge projects without explanations overwhelms me, but I'll try. I don't quite understand the bare minimum that needs to be included in a plugin for it to work.

You do not need to check the whole project, only 3 files that I've mentioned.

The bare minimum for plugin to be loaded by the engine is function "int AGS_PluginV2()", which must be present and return anything except 0.
Code: ags
int AGS_PluginV2()
{
    return 1;
}

For DLL to be compiled for Windows there has to be "DllMain", which again does not have to do anything, just return TRUE.
https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain

Anything beyond that is required if you need plugin to do something specific.

Kara Jo Kalinowski

#4



What is all of the things I have to export from the plugin to stop getting errors? Just this doesn't work:

Code: ags
#include <Windows.h>

int AGS_PluginV2()
{
    return 1;
}

// DllMain - standard Windows DLL entry point.
// The AGS editor will cause this to get called when the editor first
// starts up, and when it shuts down at the end.
BOOL APIENTRY DllMain(HANDLE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }

    return TRUE;
}

I don't really want to keep solving this one error at a time until it stops erroring... I don't understand. I need a starting point. I had tried some other code that chatgpt gave me and it wasn't completely solving my issues, I thought I might be missing a dependency or something. Anyways, I'm too tired to understand this now, if nothing else, I'll keep trying tomorrow.

Crimson Wizard

Looks like I forgot about AGS_GetPluginName. This is required for the Editor.
Why using ChatGPT when I gave you a link to a working plugin source?
Here are the functions which are exported for the Editor by my plugin, which I linked previously:
https://github.com/ivan-mogilko/ags-spritevideo/blob/46b34f4470156f48f4c8ae0f8b865d167166af49/ags_spritevideo/EditorPlugin.cpp#L102-L149

I cannot tell much about the second error. It depends on which configuration and which MSVS you are building.
Perhaps, try building in Release configuration before testing: Debug configuration usually links some extra dependencies.

Kara Jo Kalinowski

#6
I'm really trying here, but I can't figure out how to make sure those functions get exported. I included the code from those files you mentioned. I need to include Common.h, all of Common.h's dependencies, and so on? I tried using the console and it doesn't appear to be exporting any functions. I don't know what code causes the functions to be exported.

agsplugin.h has this:

Code: ags
DLLEXPORT const char * AGS_GetPluginName(void);

EditorPlugin.cpp has

Code: ags
LPCSTR AGS_GetPluginName()
{
    // Return the plugin description
    return "SpriteVideo Plugin";
}

Again, I've not worked with DLL files, my brain isn't good at reading code I've never worked with and understanding it without explanations.

I just want to make something simple showcasing how information is passed back and forth between the DLL such as AGS reading the result of a function which returns "Hello, world" and similarly a function accessing some data within AGS using the DLL.

Crimson Wizard

Quote from: Kara Jo Kalinowski on Tue 18/02/2025 16:47:17I'm really trying here, but I can't figure out how to make sure those functions get exported. I included the code from those files you mentioned. I need to include Common.h, all of Common.h's dependencies, and so on? I tried using the console and it doesn't appear to be exporting any functions. I don't know what code causes the functions to be exported.

I don't understand anything you've just said. Export what functions? What is "Common.h"? Which console?

Kara Jo Kalinowski

Quote from: Crimson Wizard on Tue 18/02/2025 17:06:27
Quote from: Kara Jo Kalinowski on Tue 18/02/2025 16:47:17I'm really trying here, but I can't figure out how to make sure those functions get exported. I included the code from those files you mentioned. I need to include Common.h, all of Common.h's dependencies, and so on? I tried using the console and it doesn't appear to be exporting any functions. I don't know what code causes the functions to be exported.

I don't understand anything you've just said. Export what functions? What is "Common.h"? Which console?

-The first error message. AGS_GetPluginName not exported from plugin. What is exporting it from the plugin? I've included all the code related to AGS_GetPluginName and nothing is being exported from the plugin.



Seems to show no functions are being exported.

EditorPlugin.cpp has an include "Common.h" but if I comment that out, it builds.

I have

EditorPlugin.cpp https://pastebin.com/GTERQdXu (commenting out the Common.h include)
agsplugin.h https://pastebin.com/N9GDp2m5
dllmain.cpp
Code: ags
#include <Windows.h>
#include "agsplugin.h";
#include "EditorPlugin.cpp";

int AGS_PluginV2()
{
    return 1;
}

// DllMain - standard Windows DLL entry point.
// The AGS editor will cause this to get called when the editor first
// starts up, and when it shuts down at the end.
BOOL APIENTRY DllMain(HANDLE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }

    return TRUE;
}

I am missing something fundamental and I don't know what I am missing, because I don't know it.

Crimson Wizard

#9
Right, so you need to declare one compiler macro: THIS_IS_THE_PLUGIN.
In which case DLLEXPORT macro will become properly defined when you compile DLL, and functions become exported AFAIK.

You may either do
Code: ags
#define THIS_IS_THE_PLUGIN
before including "agsplugin.h"
or add THIS_IS_THE_PLUGIN to the Preprocessor Definitions in the project settings.


EDIT: I don't know why, but this is not explained in the manual.
Actually, nothing is explained in the manual.

Kara Jo Kalinowski

Quote from: Crimson Wizard on Tue 18/02/2025 17:20:39Right, so you need to declare one compiler macro: THIS_IS_THE_PLUGIN.
In which case DLLEXPORT macro will become properly defined when you compile DLL, and functions become exported AFAIK.

You may either do
Code: ags
#define THIS_IS_THE_PLUGIN
before including "agsplugin.h"
or add THIS_IS_THE_PLUGIN to the Preprocessor Definitions in the project settings.

Thank you, that worked. For the second error...

I am using x86 release. The only thing I changed in the settings was turning precompiled headers off. VS 2022 free


Crimson Wizard

When a C or C++ program is built with MSVS, it will require corresponding VC runtime redistributable installed on the system. This depends on the selected Windows SDK and platform toolset (these may be found in project settings).

Supposedly, if you're using VS 2022, then you may use the generic VC redist for 2015-2022 versions, found here:
https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version

Kara Jo Kalinowski

Quote from: Crimson Wizard on Tue 18/02/2025 17:59:45When a C or C++ program is built with MSVS, it will require corresponding VC runtime redistributable installed on the system. This depends on the selected Windows SDK and platform toolset (these may be found in project settings).

Supposedly, if you're using VS 2022, then you may use the generic VC redist for 2015-2022 versions, found here:
https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version

I have both the 64 bit and x86 versions installed. The dependencies listed here I have confirmed are in windows/system32 or a subfolder. I am compiling this DLL for x86 since AGS is 32-bit, I believe.


Crimson Wizard

Well, I cannot tell what may be the problem without seeing the project or dll.

My plugin's dll has only 2 dependencies according to dumpbin: kernel32.dll and user32.dll.
Although I compiled it with VS 2015.



Crimson Wizard

Well, it works for me. And the dummy plugin that I made in VS 2019 right now also has exact same dependencies:
https://github.com/adventuregamestudio/ags-demo-plugins/

Which version of AGS do you have installed on your computer right now?
Have you tried installing VC Redist 2015-2022 that I linked above?

Kara Jo Kalinowski

AGS Editor .NET (Build 3.6.1.25)

I installed both the 64 and 86 versions of the thing you linked above.

Actually, I tried it in 4.00.00.14 and it works there.

Kara Jo Kalinowski

#17
Actually never mind... I forgot to delete an older version of the DLL... I didn't realize which DLL it was giving me problems about :/

Okay, now to try and figure out how to actually make something. Thanks

When distributing games made with plugins do I also need to distribute the visual c libraries?

Crimson Wizard

I was not thinking clearly lately.

There are two ways to build a C++ program in MSVS:
- dynamically linking runtime VC libs; this means that the program expects them to be installed in the system;
- statically linking runtime VC libs; this means that the program will be linked with necessary libs at build time.

Engine does the latter, that's why you don't have to install these VC redist libs along with the games.

So you can do the same with plugins.

This is done by going into project properties:
-> C/C++
-> Code Generation
-> Runtime Library
=> set it to
   * for Release config: Multi-threaded (/MT)
   * for Debug config: Multi-threaded Debug (/MTd)

And rebuild. Then it should not require any extra installations at a cost of DLL becoming somewhat bigger.

Kara Jo Kalinowski

I added this to the ourScriptHeader in EditorPlugin.cpp

Code: ags
"import const char* HelloWorld();\r\n"

Then this in the .cpp file

Code: ags
const char *HelloWorld() {
    return "Hello World";
}

void AGS_EngineStartup(IAGSEngine* lpEngine) {
    engine = lpEngine;
    engine->RegisterScriptFunction("HelloWorld", (void*)HelloWorld);
}

At first I tried just the cpp file stuff but the editor wasn't recognizing the HelloWorld function. Adding the other line allowed the editor to recognize the function

Line 59:   
Code: ags
Display(HelloWorld());

__Plugin100.ash(59): Error (line 59): Cannot create pointer to basic type

What am I doing wrong? Thanks.


SMF spam blocked by CleanTalk