Chaos Project

RPG Maker => RPG Maker Scripts => Topic started by: Heretic86 on May 02, 2014, 10:50:41 pm

Title: I made a DLL! Now what?
Post by: Heretic86 on May 02, 2014, 10:50:41 pm
So just screwing around with a tutorial here (http://forums.rpgmakerweb.com/index.php?/topic/17708-tutorial-writing-your-own-dll-and-calling-it-in-rm/) and am messing around with it.

First issue I ran into is it seems that this only compiles to C not C++?  Next is the Win32API, which some have said also limits Ruby interactions with DLLs?  Then we get P, I, L, for Strings, Integers, and Longs.  So how do we throw Arrays as arguments to the DLLs?  I know its possible, just not sure how to pull it off.  Now what about Bitmaps, or pointers to whats in RMXP's memory for messing with Graphics?

First thing Im having an issue with is just adding a second function / method to the DLL.

The "hello" example in the DLL works fine.  Called in RMXP by using:

myFunc =  Win32API.new("test.dll", "hello", "I", "I") # Integer In, Integer returns

then myFunc.call(arg)

It allows me to toss an integer at the DLL, right now Im just incrementing, then spits back out a number to get spit back out.  Data in, Data out.  Thats all I cared at this point.  So trying to add another function, called it "goodbye" in the DLL and it compiles fine, but when I try to make RMXP call to the new function, I get: "runtime error occured", "GetProcAddress: goodbye or goodbyeA".

What did I do wrong?
Title: Re: I made a DLL! Now what?
Post by: G_G on May 03, 2014, 01:03:05 am
For every function you want to use in Ruby, you have to export it.

#define MY_FIRST_DLL __declspec(dllexport)

extern "C" MY_FIRST_DLL
int hello(void);


extern "C" telling the compiler to use C-style function names instead of C++. The "MY_FIRST_DLL" constant that was defined, is just a shortcut to use instead of typing out "__declspec(dllexport)" for every function. I recommend changing MY_FIRST_DLL to DLLEXPORT or something similar. Then in your header file, you can do this:
extern "C" DLLEXPORT int hello(void);
extern "C" DLLEXPORT int goodbye(int data);


Source file:
DLLEXPORT int hello(void)
{
}

DLLEXPORT int goodbye(int data)
{
}


Code not actually tested, I'm just going off of the little I do know and remember. But it should be able to work something like that.
Title: Re: I made a DLL! Now what?
Post by: Heretic86 on May 03, 2014, 03:44:31 am
Actually, code works fine.  So what would be the next logical step?  Most stuff I wouldnt need a DLL for, so need something else to go after.  Graphics in DLLs are probably a bit over my head at this time, but get there eventually.  Whats another good step to take here?
Title: Re: I made a DLL! Now what?
Post by: Blizzard on May 03, 2014, 06:01:13 am
I just want to add that I think C++ DLLs can work, but they have to have a C API interface (as gameus already said). In any case, yes, only C is supported.

Also, you don't need DLLEXPORT in the source files if you include the header on top. It makes things a bit easier to maintain.
Title: Re: I made a DLL! Now what?
Post by: G_G on May 03, 2014, 10:24:04 am
There's a topic on HBGames and the guy taught people how to access bitmap data in libraries. There have been numerous releases of graphics modifications using libraries since C is much faster than Ruby, so the pixel by pixel changes are much faster.

I don't really remember how to do it and I can't find the topic. But bitmap alteration might be the only thing you can take on with just a library. I remember using DirectX to try and draw a couple of triangles on the screen and it caused flickering really bad. But even if you were to replace all the rendering that the RGSS module does, you'd be better off creating your own game engine since it'd give you more control.
Title: Re: I made a DLL! Now what?
Post by: KK20 on May 03, 2014, 10:45:12 am
Poccil's tutorial:
http://www.hbgames.org/forums/viewtopic.php?f=11&t=39324

Guy trying to use said tutorial:
http://www.hbgames.org/forums/viewtopic.php?f=180&t=70274
Title: Re: I made a DLL! Now what?
Post by: ThallionDarkshine on May 03, 2014, 07:13:21 pm
If anyone is interested, to pass arrays to a dll, you simply create a ruby array, and call the pack method to pack it into something that can be passed to a win32api method. Ex.
Code: ruby
Array.new(10) { 0.0 }.pack("f*")

When receiving an array value in the dll, you take it in as a pointer to whatever type you are sending in. For example, for the array from the ruby example, the cpp type would be
Code: cpp
float*



Also, for passing bitmaps, you simply pass
Code: ruby
bmp.__id__

If you left shift this value after it is passed into the dll, you get a pointer to a windows bitmap that is defined by the following structure:
Code: cpp

typedef struct {
   DWORD flags;
   DWORD klass;
   void (*dmark) (void*);
   void (*dfree) (void*);
   double *data; //red is index 1, green is index 2, blue 3, alpha 0
} RGSSCOLOR;

typedef struct{
   DWORD unk1;
   DWORD unk2;
   BITMAPINFOHEADER *infoheader;
   RGSSCOLOR *firstRow;
   RGBQUAD *lastRow;
} RGSSBMINFO;

typedef struct{
   DWORD unk1;
   DWORD unk2;
   RGSSBMINFO *bminfo;
} BITMAPSTRUCT;

typedef struct{
   DWORD flags;
   DWORD klass;
   void (*dmark) (void*);
   void (*dfree) (void*);
   BITMAPSTRUCT *bm;
} RGSSBITMAP;


Edit - Oops, most of this is completely covered by KK20's links.
Title: Re: I made a DLL! Now what?
Post by: orochii on May 03, 2014, 10:52:13 pm
This topic is a mine of gold.
Title: Re: I made a DLL! Now what?
Post by: Heretic86 on May 04, 2014, 06:35:17 am
Thanks guys!  I need to go play around with all the stuff here, and those tutorials.  I'll probably be back shortly with questions, or I'll be busy walking my dogs.