[Tutorial] Writing your own DLL and calling it in RM

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
Here's a simple guide using visual C++ to build a DLL.

If you're using a different compiler you'll have to figure out how to get it to build DLL's that are compatible with win32API calls

Get visual C++

Download visual C++ from microsoft. Any version should be fine. I just get the express edition since it's free.

Setting up a project

If you are going to build your DLL through the IDE, you should set up your project so that the IDE automatically builds a DLL.

1. Create a new project (ctrl+shift+N)

2. Select win32 console application

3. Choose a name, hit OK

Another wizard will come up.

4. Next

5. Select "DLL" and "Empty Project"

6. Finish

Now right-click on the the "Header Files" and add a header file, and right-click "Source Files" and add a code file.

Getting cl and setting it up

If you're going to compile your DLL via command-line manually, you will need to set up your environment first.

1. Go to your installation folder -> VC -> bin and you should see "vcvars32.bat"

2. Open command-line and then run that batch file to set up the environment.

3. Type cl and press enter and it should work.

Step 2 is optional; you can set your env vars to include visual studio folders.

Writing some code

Here's a header and code file

test.h

#define MY_FIRST_DLL __declspec(dllexport)extern "C" MY_FIRST_DLLint hello(void);test.cpp
Code:
#include "test.h"MY_FIRST_DLLint hello(void){   return 1;}
Don't forget the extern "C" otherwise your calls from within RM will fail.Building your DLL

Now you can build your DLL. You can either build it through the IDE, or through command-line using the cl.exe compiler. I would recommend the IDE since it does a lot of optimizations for you.

Building in the IDE

1. In the menu, click Build --> Build Solution

2. If everything works, you should have your DLL in your project folder

That's it. Typically you should set the build configuration to "release" instead of "debug".

You might see this in a dropdown near the top, or you will need to go to Build --> Configuration Manager and set the current active configuration.

Building in command-line

Here's some basic instructions that don't consider any optimization settings. You can look up the compiler flags if you want.

The following command will build a DLL

cl /LD test.cpp /Fetest.dllBasically- LD specifies you are making a DLL

- Fe renames the output file. Useful if you want the output name to be different from the source filename

Now you should get a bunch of files (test.obj, test.exp, test.lib, etc) along with the test.dll you want. At some point you will probably want to look at optimizing your stuff.

Calling your DLL

Now that you have your DLL just make a project and create an object for your DLL function

myFunc = Win32API.new("test.dll", "hello", "", "L")The four arguments that are passed in are- the path to the DLL (rooted under your project)

- the name of the function you want

- the types of the arguments that you want to pass in. Could be an array of strings like ['L', 'P', 'L'] or a single string "LPL". Probably more variations.

- Type of return value

The types of the arguments are easy enough: just use whatever your function signature wants.

The return value is also pretty straightforward. You'll probably be working with integers/longs and pointers for the most part.

Now you can call your function, passing in the appropriate arguments (in this case nothing)

p myFunc.call()After making the call, you should see that 1 printed out successfully in your console.That's pretty much it. At this point it's just a matter of figuring out how to write your code and how to pass things back and forth.

Note: the only reason I'm writing DLL's is because certain things are too slow in ruby to be feasible, such as image processing. If I can do it in ruby and it's fast "enough", I would stick with Ruby since it makes it much easier to fix and build on.

Reference

Compiler options for cl

http://msdn.microsoft.com/en-us/library/fwkeyyhe.aspx

Parameter types and their symbols

http://rubyforge.org/docman/view.php/85/3463/API.html#M000001 (suggest better reference)

Thanks to Zeriab and Solistra for the steps to get RM to talk to a DLL.

MGC for directing me to the compiler used in visual C++
 
Last edited by a moderator:

Zeriab

Huggins!
Veteran
Joined
Mar 20, 2012
Messages
1,268
Reaction score
1,422
First Language
English
Primarily Uses
RMXP
I have RMXP experience only. It might be different for other VX and Ace.

I have used Visual Studio 2008 to create a DLL file. It had a template for creating such files, which helps quite a lot.

Be aware of the extern "C" which seems to be required for communication with RM.

Note that if you are using Visual Studio 2008 you should include Microsoft Visual C++ 2008 Redistributable. For 2010 the similar 2010 redist.

You can install it silently with the /q command I think.

I know this isn't what you requested, but hopefully it is enough. From my point of view Zeus81 seems to be the most well-versed scripter in this matter, so you can try asking him for help.

Good luck either way.

*hugs*

 - Zeriab
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
It's good to know that I can use visual studio for this since I'm using that atm). Knowing about the extern C is probably enough to get things going.


What do you mean by including the redistributable?
 
Last edited by a moderator:

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,682
Reaction score
3,003
First Language
Tagalog
Primarily Uses
RMVXA
extern C makes the compiler export the functions I think which makes them readable by other assemblies... I've been trying to make this on VB.net but I can't make it work... maybe I just really need to learn some C++...
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
I think Zeriab's talking about the templates that come with visual studio. The one where you start a new project or add a new file and it asks what kind of file you are creating.
 

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,682
Reaction score
3,003
First Language
Tagalog
Primarily Uses
RMVXA

Solistra

Veteran
Veteran
Joined
Aug 15, 2012
Messages
593
Reaction score
247
Primarily Uses
Also, extern "C" doesn't make functions externally available. That's what __declspec(dllexport) does in C and C++. The extern "C" block tells the compiler to link with C-style function names rather than C++-style, as the two are fundamentally incompatible when left to their own devices.
 

Zeriab

Huggins!
Veteran
Joined
Mar 20, 2012
Messages
1,268
Reaction score
1,422
First Language
English
Primarily Uses
RMXP
Thanks Solistra :D

For the redistributable I mean this: http://support.microsoft.com/kb/2019667

Remember to pick the right version.

In the header file I typically do something like this:

#define DLLEXPORT __declspec(dllexport)extern "C" DLLEXPORT int myMethod(void)extern "C" DLLEXPORT int sendMessage(const char* id)
Then in the .cpp file reuse the definition:

DLLEXPORT int myMethod(void){    return 42;}DLLEXPORT int sendMessage(const char* id){    return -1;}
The danger in that can be to forget about __declspec(dllexport) as I did until Solistra mentioned it >_>

*hugs*
 

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,682
Reaction score
3,003
First Language
Tagalog
Primarily Uses
RMVXA
so I tried to do something like Zeriab's example and came up with this, I cannot seem to use it in Sharp dev... cannot test it in RM right now... can anyone try it out?

it has a function named CompName inside which takes void and returns char*

BTW, I wrote the .cpp and .h in notepad by copying and editing Zeriab's code then compiled it into a dll in code blocks...

PS: Sorry if this can be considered hijacking... I just felt like it doesn't deserve it's own thread as I only want to know if it works for others...
 
Last edited by a moderator:

Zeriab

Huggins!
Veteran
Joined
Mar 20, 2012
Messages
1,268
Reaction score
1,422
First Language
English
Primarily Uses
RMXP
I would suggest a different approach for the CompName method.

Let it take an unsigned integer (make it a constant) and a char* buffer.

Change the buffer with the computer name.

Return the size of the information in the buffer.

In Ruby you should ensure the string is null-terminated (use say "\0" * 256) though of course in C++ you should check for errors in that assumption. (Contest it basically)

With the return integer you can extract the information from the buffer.

*hugs*

 - Zeriab
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
Thanks to zeriab and solistra it was easy to call my dll functions.

If I am distributing my DLL will others need to install the appropriate redistributable package? Or is everything bundled up in the dll automatically?

It is convenient that anything I write to stdout in the dll basically shows up in RM's console, as testing my code in visual C++ didn't seem very efficient especially since it automatically built a DLL for me (which is great, except when I want to actually see if my code works)

The rest of it is just figuring out how to write stuff in C++ and figuring out how some of the objects are stored in memory (the code for processing Bitmap objects are floating around in several places like here or here but haven't found anything for the other ones like Table or Tilemap)

Anyways using the bitmap structs given above, I've got what I need to grab each pixel in a bitmap

Code:
#include "stdafx.h"#include "rgssAPI.h"#include "Windows.h"RGSS_API int parseBitmap(unsigned long object){    RGSSBMINFO *bitmap;    long width;    long height;    RGSSRGBA *row;    float red,green,blue;        bitmap = ((RGSSBITMAP*)(object<<1))->bm->bminfo;    width = bitmap->infoheader->biWidth;    height = bitmap->infoheader->biHeight;    row = bitmap->lastRow;    for (int y = 0; y < height; y++)     {            for (int x = 0; x < width; x++)         {            red = row->red;            green = row->green;            blue = row->blue;            row++;        }    }}
Does anyone know how the Table object is stored in memory?
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
Updated thread name and first post with a tutorial.


The compiler for visual C++ is a fairly large download, mainly because you're going to get the IDE and everything else with it.


If you went with the windows SDK download and only grabbed the compilers, you're still in for about 100 MB it seems.


If anyone else is using other compilers it would be good to know how to make DLL's with them.


Also if there's a way to get the visual C++ compiler without requiring to download large files that would be useful as well.

I would suggest a different approach for the CompName method.


Let it take an unsigned integer (make it a constant) and a char* buffer.


Change the buffer with the computer name.


Return the size of the information in the buffer.


In Ruby you should ensure the string is null-terminated (use say "\0" * 256) though of course in C++ you should check for errors in that assumption. (Contest it basically)


With the return integer you can extract the information from the buffer.


*hugs*


 - Zeriab
Why might I use this over just having the computer figure out how much memory it needs?
 
Last edited by a moderator:

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

How many parameters is 'too many'??
Yay, now back in action Happy Christmas time, coming back!






Back in action to develop the indie game that has been long overdue... Final Fallacy. A game that keeps on giving! The development never ends as the developer thinks to be the smart cookie by coming back and beginning by saying... "Oh bother, this indie game has been long overdue..." How could one resist such? No-one c
So I was playing with filters and this looked interesting...

Versus the normal look...

Kind of gives a very different feel. :LZSexcite:
To whom ever person or persons who re-did the DS/DS+ asset packs for MV (as in, they are all 48x48, and not just x2 the pixel scale) .... THANK-YOU!!!!!!!!! XwwwwX

Forum statistics

Threads
105,853
Messages
1,016,986
Members
137,561
Latest member
visploo100
Top