Please login or register.

Login with username, password and session length
Advanced search  

News:

For WME related articles and tutorials visit WME Resource Center.

Author Topic: My first and simple (and useless) DLL for WME  (Read 5555 times)

0 Members and 1 Guest are viewing this topic.

Jerrot

  • Global Moderator
  • Addicted to WME forum
  • *
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 690
    • View Profile
My first and simple (and useless) DLL for WME
« on: April 05, 2003, 07:29:25 PM »

hi,

hey, the dll support works.  ;D

just wrote my first DLL (of course it's absolutely useless, since WME has its own Date Object) but maybe helpful for bloody C++ beginners like me. I got that "extern ..." line from some VC5 tutorial, maybe this is outdated, but it works.

Code: [Select]
this is my currenttime.dll :

#include <time.h>
#include <string.h>
extern "C" __declspec(dllexport) char *GetCurrentTime()
{
   char *line="";
   struct tm * tm1;
   time_t caltime;

   caltime = time(NULL);
   tm1 = localtime(&caltime);

   strftime(line, 200, "%I:%M:%S", tm1);
   return line;
}

and in the WME-Script:

Code: [Select]
external "currenttime.dll" string GetCurrentTime();
actor.Talk("Oh, it's "+GetCurrentTime()+" ! Time to lunch !");

 :D
Logged
Mooh!

Mnemonic

  • WME developer
  • Administrator
  • Addicted to WME forum
  • *
  • Karma: 41
  • Offline Offline
  • Gender: Male
  • Posts: 5683
    • View Profile
    • Dead:Code Site
Re:My first and simple (and useless) DLL for WME
« Reply #1 on: April 06, 2003, 09:51:01 AM »

Hey Jerrot, you're fast! ;D Cool!

...although, may I have some suggestions? I don't think the C code is exactly safe, because you don't allocate enough space for the "line" string. Although you tell the strftime function that it can use up to 200 characters, the variable is actually initialized as one character. Plus, you are returning out a local variable, which gets destroyed after the function finishes.
In this case where you need to return a non-constant string from a DLL function, it's better to pre-allocate a string buffer in WME script and pass it to the function. This is how the Windows API functions work.

Oh yeah, strings in C suck! ;)
Logged
Yes, I do have a twitter account
Please don't send me technical questions in private messages, use the forum. ::wave

Jerrot

  • Global Moderator
  • Addicted to WME forum
  • *
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 690
    • View Profile
Re:My first and simple (and useless) DLL for WME
« Reply #2 on: April 06, 2003, 10:47:44 AM »

Hey Mnemonic,

oh yes, C and strings... it took me about half an hour to pass the string back to WME. I defined the "line" string with char[200] before, but then the compiler told me what you wrote next: I'm returning a local variable. Strange, that it doesn't report this anymore with char *line=""; ! But sure, you're right... thanks!

In this case where you need to return a non-constant string from a DLL function, it's better to pre-allocate a string buffer in WME script and pass it to the function. This is how the Windows API functions work.

Uhm, okay... I understand what to do, but I don't know how, I just tried it somehow, but it crashed. Would you mind to correct my code when you've got a free minute ?  ::)

Oh, and what about that "extern ..." line ? I'm using VC++6.0 and when I create a new "simple DLL project", it creates something like this :

Code: [Select]
#include "stdafx.h"

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                )
{
    return TRUE;
}

Can you or anybody tell me ANYTHING about it ?  :) No "extern..." line and for me... well I just don't understand it yet and any help is welcome, thanks!!
Logged
Mooh!

Mnemonic

  • WME developer
  • Administrator
  • Addicted to WME forum
  • *
  • Karma: 41
  • Offline Offline
  • Gender: Male
  • Posts: 5683
    • View Profile
    • Dead:Code Site
Re:My first and simple (and useless) DLL for WME
« Reply #3 on: April 06, 2003, 12:48:43 PM »

Sure, this is how I'd do it:

From the C++ side, this is the source of the DLL:
Code: [Select]
#include <time.h>


extern "C" __declspec(dllexport) void GetCurrentTime(char* StringBuffer, int BufferSize)
{
   struct tm* tm1;
   time_t caltime;
   
   caltime = time(NULL);
   tm1 = localtime(&caltime);
   
   strftime(StringBuffer, BufferSize, "%I:%M:%S", tm1);
}

Note that the string buffer comes as a parameter and out function only fills the buffer.
Now what the declaration says:

__declspec(dllexport) - This tells the compiler to export this function off the DLL. There are other ways of marking functions as exported, but this is the easiest one (although it's Visual C++ specific).

extern "C" - This tells the compiler to use a C naming convention for the function. This is only necessary if you're using C++ for writing your DLL. C++ naming convention is different, it uses so called "decorated names". It means the name of the function contains encoded information about it's parameters and other information. If you would't use the extern "C" specifier, your function would be exported as something like "?GetCurrentTime@@YAXPADH@Z".

The DllMain function generated by the wizard denotes an entry point of the DLL library. This function gets called whenever the DLL is being loaded or attached to a new process (and also when it's being detached). You can use this function to initialize your DLL's internal data. But you don't need to write this function. If you don't, the compiler will provide a default (empty) DllMain function.

Now, from the WME script it would look like this:
Code: [Select]
external "wme_dll.dll" cdecl GetCurrentTime(string, int);

var Str = new String(200);
GetCurrentTime(Str, 200);
actor.Talk("Oh, it's " + Str + " ! Time to lunch !");

Ok, it a bit more complicated than your original code, but it's safe :-) You create the string buffer in the WME script and pass the buffer to the DLL function to fill it.
Note the "cdecl" calling convention. It's C default. If you don't specify it, WME will default to "stdcall" convention and you'll get warnings in the WME log file.

I have uploaded the DLL project source at: http://dead-code.org/misc/wme_dll.zip
Logged
Yes, I do have a twitter account
Please don't send me technical questions in private messages, use the forum. ::wave

Jerrot

  • Global Moderator
  • Addicted to WME forum
  • *
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 690
    • View Profile
Re:My first and simple (and useless) DLL for WME
« Reply #4 on: April 06, 2003, 01:27:00 PM »

Thanks Mnemonic, that was very helpful!  :D

Now, from the WME script it would look like this:
Code: [Select]
external "wme_dll.dll" cdecl GetCurrentTime(string, int);

var Str = new String(200);

Oh! I didn't know I can declare variables that common way!
(doc: "WME script is a loosely typed language.") That's good!

Note the "cdecl" calling convention. It's C default. If you don't specify it, WME will default to "stdcall" convention and you'll get warnings in the WME log file.

Cool, that solved my last problem ("stack corrupted"...). Thank you so much, now, let's think about more useful plug-ins.  ;)

Greetings, Jerrot.
Logged
Mooh!

Jerrot

  • Global Moderator
  • Addicted to WME forum
  • *
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 690
    • View Profile
Re:My first and simple (and useless) DLL for WME
« Reply #5 on: April 07, 2003, 09:17:41 AM »

Oh! I didn't know I can declare variables that common way!

@Mnemonic again:
I feel sooo stupid, you wrote all the answers to my questions before in the html documentation file of the last build, about cdecl, about the strings and about the "extern" line... sorry... I just didn't read close enough ! ::)
Logged
Mooh!

Mnemonic

  • WME developer
  • Administrator
  • Addicted to WME forum
  • *
  • Karma: 41
  • Offline Offline
  • Gender: Male
  • Posts: 5683
    • View Profile
    • Dead:Code Site
Re:My first and simple (and useless) DLL for WME
« Reply #6 on: April 07, 2003, 10:08:36 AM »

Hehe, no problem ;D
(I'm aware of the fact no one reads the docs anyway ;))
Logged
Yes, I do have a twitter account
Please don't send me technical questions in private messages, use the forum. ::wave

Tom King

  • Guest
Re:My first and simple (and useless) DLL for WME
« Reply #7 on: February 18, 2004, 08:34:09 PM »

Hey now, I'm reading them! I can't imagine trying to barge in without there existing some form of documentation to get me started/troubleshoot with.  Thanks for all the hard work!

Tom (newguy)
Logged
 

Page created in 0.056 seconds with 20 queries.