Jump to content


Photo
* * * * * 6 votes

How To Make A Dll


  • Please log in to reply
50 replies to this topic

#1 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 10 November 2008 - 07:35 PM

  • Title: How To Make A Dll in C++
  • Description: describing the necessary steps to create a DLL in C++
  • GM Version: - (ANY)
  • Registered: yes
  • File Type: In-topic tutorial, with a supportive zip file.
  • File Size: 2.5 MB
  • File Link: Download cpp_dll_tutorial.zip from Host-A
  • Required Extensions: -
  • Required DLLs: -
Summary
This tutorial will teach one what the necessary steps are to write a DLL in C++. The tutorial covers everything from creating a C++ project to using the exported DLL in gamemaker. As prerequiste one should have decent understanding of C++, classes, pointers, heap vs stack are used without explanation.

*Revised and modified by paul23
*Last edited: 10/01/2013
*original tutorial
http://gmc.yoyogames...dpost&p=3868901


Introduction
Making a DLL is not that hard, but setting up the very first time is tedious. This tutorial teaches the specific points of DLLs, how to create a dll & how to call your own created dlls from Gamemaker.
To fully understand this tutorial a solid knowledge of C++ should already be gained. Please remember the GMC is aimed at Gamemaker, and hence specific questions about the C++ language should be asked elsewhere.


The included zip file contains examples used through this tutorial. Each example (except the last) contains 2 folders, the c++ folder with the source & the GM folder with a click 'n go compilation of the example. The supportive zip can be found here.

Part 1-Setting Up
As this tutorial covers writing dlls in C++ you'll need an IDE/compiler for C++. While there are many more compilers this tutorials uses 2 compilers, both are free:
Visual studio express. Excellent ide with integrated compiler, the intellisense is among the best features, and the integrated debugger is just amazing. If you ever wish to get too serious into developing for windows, you can easily switch to the (expensive) professional options.
Code::Blocks Another amazing option. Comes with the GCC compiler - and having by the most features of the new C++11 standard implemented. Also if one wishes to work cross-platform this is the ide of choice.

One thing I strongly urge everyone: do not use DEV-C++. This ide hasn't been updated for years, has many bugs and lacks many features. The compiler which comes with default to this IDE is subpar in performances and not up to date.


Create an DLL with visual studio
  • Go to file -> new -> new project (ctrl+shift+N)
  • select "win32 application" and type your DLL name in the name field
    ZMkxMHQt.png
  • Press ok
  • Press next
  • Choose as application type "DLL" & tick the box "empty project"
    wzlEXwOt.png
  • Press finish
  • Add a C++ source file.
    • right click source folder
      Uogx0Vet.png
    • select C++ file - give it your "main" name)
      ArI3QYjt.png
  • Compiling is done with pressing F7 (or F5).
  • When developing make sure the project configuration is set to "debug" (see middle top of visual studio bars).
  • When releasing make sure the project configuration is set to "release"
    newdlloptions.th.png
  • Dlls are found in the <PROJECTNAME>/debug or <PROJECTNAME>/release folder. (up to the reader to decide which one to give to others tongue.gif)
  • C-runtime
    An often misunderstood concept is that of the C-runtime behaviour. C-runtime are parts that each compiler should provide to handle input-output, and starting/closing applications. In visual studio one can go several ways to "include" this. Either you can link statically -which means the code is included inside the executable- or link dynamically -then a common windows dll is used-. The dlls used are MSVCR100.dll & MSVCP100.dll. Each windows install includes those "by default", however with each new version of visual studio a new dll also comes out, and older OSes might not include the runtime. (IE: windows 98 won't have those dlls, nor will people who choose not to update windows).
    If you wish to be 100% sure everyone can run your dll you can link statically. However consider that the dll will then become anywhere between 50 kB & 1 MB larger in size.
    To include statically you have to go open the project properties -> c/c++ -> code generation -> runtime library -> select "multithreaded (/MT)" instead of multithreaded DLL. (Or multithreaded debug (/MTd) )
    In the last section of this tutorial the c-runtime is explained better.



    Part 2 - Writing the DLL base

    A first function
    Let us first look at a simple function.
    #define GMEXPORT extern "C" __declspec (dllexport)
    
    GMEXPORT double SampleFunction(double a, double b) {
    return a * b;
    }
    Most of it should be easy to understand, but the first line probably looks like gibberish: that line defines GMEXPORT to be a combination of 2 function modifiers. We will return later in great depth to these. Build this small function (press F5 or F7). And you should look into your projectfolder/debug.
    There now stays a file with your <projectname>.dll. This is a dll you can use.

    Now to call this function from gamemaker. Make first a new project & copy the dll (from above) to the project directory. Now we create 2 scripts: an initialize script, and a "calling" script. - And use 1 object which in the creation event call the initialize script. And the keypress release calls the function:
    //InitDLL script:
    globalvar foo_FN;
    
    foo_FN = external_define("tutorial2.dll", "SampleFunction", dll_cdecl, ty_real, 2, ty_real, ty_real);
    //Foo script:
    return external_call(foo_FN, argument0, argument1)
    objDLL

    //create event:
    InitDLL()
    
    //KeyPress - Enter
    var res;
    res = Foo(4,5);
    show_message(string(res));
    And this should work smile.gif.
    The example files can be found in "/tutorial2/" folder of the included sources.

    name mangling
    One of the features of C++ is that you can overload functions: foo(double, double) is different from foo(char *, double) or foo(int, int). To handle this, compilers internally change names: the function double SampleFunction(double, double) would be renamed to: "?SampleFunction@@YANNN@Z".

    However as we identify functions by string, we wish the name to be left "alone". So we have to disable this name mangling (as it is compiler specific). Visual c++ can also link according to the C language rules, which doesn't have overloading (and no mangling).
    In visual studio one defines a function to use "C linkage" by preceding the function with the modifier
    extern "C"

    This also puts a few more limitations on the formulas:
    - Overloading isn't possible: each name must be unique
    - Can't use optional arguments
    - Can't be used in member functions
    - Can't be used with templates

    exporting the function
    The compiler also needs to know what functions are "exported" - which functions are only used internally and which functions can be called from outside. This is simply done by the function modifier:
    __declspec( dllexport )

    Calling convention
    There are several "conventions" of how a call to a function is made. To understand this fully one needs to understand how the registers, stack & heap work - this is out of the scope of this tutorial. However it should be understood that the convention has to be "similar" at the 2 sides of the line. If gamemaker expects it has to clean up "the stack" - yet the DLL already thought he should clean the stack, the stack becomes corrupted. Similar if both think the other will clean up, there exists a memory leak.
    There are 2 calling conventions supported in gamemaker: stdcall & cdecl. cdecl expects the caller (GM) to clean up, stdcall expects the callee (DLL) to clean up.

    As you saw in the example above the modifier for the calling convention isn't used: that is because when no convention is specified, visual studio gains the calling convention from the options. - Which are "__cdecl" by default.
    Now a more complete description of samplefunction would be:
    GMEXPORT double __cdecl SampleFunction(double a, double b) {
    return a * b;
    }
    Using stdcall is neglectibly faster: it removes literary 1 command from assembly: however it makes the functions -for the compiler- more difficult. And even if you use "c" function style it will mangle the names: a function will get a preceding "_", and after the name of the function the "@" followed by the size of arguments (in bytes) are added. The sample function is renamed to: _SampleFunction@16
    Bottom line: just use __cdecl, and don't bother with stdcall.

    Now take a second look at the small script above, you should be able to fully understand what was previously gibberish. The GMEXPORT just contains 2 function modifiers.

    DLL entry point
    Just like normal programs have an entry point: the "main" functions, so do dlls. This entry point is called by default "dllmain" (and there's little reason to change). A base setup for the dll main function is as following:
    #include <windows.h>
    BOOL WINAPI DllMain(
    HANDLE hinstDLL,
    DWORD dwReason,
    LPVOID lpvReserved
    )
    {
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
    break;
    }
    return TRUE;
    }
    First of all notice the argument types. Those aren't primitive types, they are typedefs, defined in the windows.h header. So if you wish to use the dllmain function, also include <windows.h>. The first argument is a pointer to the dll-handle. But the second argument is more important, it gives a "reason" why the dll is called. I'll summarise the reasons below:
    DLL_PROCESS_ATTACH - Is called the moment the library is loaded, and only loaded the first time for that application. - In gamemaker this means the first time you call the function "external_define".
    DLL_THREAD_ATTACH - Is called when the dll is attached to a specific thread, and for each thread it is attached it is called. - As gamemaker is single threaded this functionaility isn't used
    DLL_THREAD_DETACH - Is called when a dll binded to a specific thread is freed (not used)
    DLL_PROCESS_DETACH - Is called when the dll is freed. If the reason for freeing is an application exit, lpvReserved is non-NULL. If the library is freed because of all functions are removed, lpvReserved is NULL.

    The return value should be "TRUE" when the library loaded correctly, alternativelly "FALSE" will result gamemaker in displaying the error "failed to load ....".

    The dllmain function is perfect to allocate memory from the heap for global use (if necessary). Another standard use for the dllmain is to capturethe hinst of the DLL, which is used in some (GUI) libraries. However do notice that more complex things (loading other dlls, using system calls and many more) are not possible, better is to use an "init" function. Here a technical paper about what should and should not be done in dllmain can be downloaded.


    Part 3 - Functions in DLLS
    During this part the layout of functions will be discussed. It should already be understood what the function modifiers are and why to use them. This part will also describe many practical challenges (and ways to solve them) c++ programmes face when working for gamemaker. For the rest of this section we consider in each codepiece the <windows.h>, the <string> & the <sstream> headers to always be included - They aren't necessary for dlls (and shouldn't be in your dlls by default). However we use parts of these headers for "debug" messages. Specifically the "MessageBoxA( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);" function & stringstreams to convert numbers to c++ strings in a C++ way. (Note that in more advanced programs you're better of using boost::lexical_cast - however this requires a third party library and isn't included in this tutorial). The start of the main file will hence look like:
    #include <string>
    #include <sstream>
    #include <windows.h>
    #define GMEXPORT extern "C" __declspec (dllexport)
    
    template <typename T>
    std::string to_string(const T & value) {
    std::stringstream sstr;
    sstr << value;
    return sstr.str();
    }
    variable types
    There are 2 types of variables gamemaker can understand: 64bit floating point precision numbers & null-terminated character arrays. - In c++ represented by "double" & "char *", in gamemaker "real" and "string". All data has to be fitted in these two types.

    Passing arguments to C++
    Passing doubles is very easy, just define a function to take a double as argument: SampleFunction(double a, double b )
    Also passing character arrays is easy: SampleFunction(char *a, char *b ) As we work with C++ I strongly urge everyone to translate the character array to a std::string immediately, and perform operations on that string. Two examples:

    #include <windows.h>
    #include <string>
    #include <sstream>
    #define GMEXPORT extern "C" __declspec (dllexport)
    
    
    template <typename T>
    std::string to_string(const T & value) {
    std::stringstream sstr;
    sstr << value;
    return sstr.str();
    }
    
    
    
    GMEXPORT double SampleFunctionNumbers(double a, double b) {
    std::string mynum(to_string(a * b));
    mynum += " is the multiple of the given arguments";
    ::MessageBoxA(NULL, mynum.c_str(), "message box", MB_ICONINFORMATION);
    
    return 0;
    }
    GMEXPORT double SampleFunctionCharArrays(char * a, char * b) {
    std::string mynum(a);
    mynum += std::string(b);
    mynum += " is the given arguments combined";
    ::MessageBoxA(NULL, mynum.c_str(), "message box", MB_ICONINFORMATION);
    
    return 0;
    }
    Can be found in the "tutorial3" section of the included file.

    Returning numbers
    Returning a type such as doubles is very easy, just specify the return type (AS DOUBLE!) - and use return ... like you would normally. You can see how to use these things in the examples above. The doubles can be used directly as numbers in gamemaker, and no conversion has to be made.

    Returning strings
    Strings are a bit more difficult to use than doubles. Basically what you wish to return is a character array. - So set the return type to char *. Now experienced C++ programmers will immediately see a troubling point here (which is a good reason for using std::strings instead of char * as much as possible). the "value" of char * is simply a pointer to the start of the character array. The actual data contained in the array has to be managed manually. If one would go naively and do something like:
    char * myfun() {
    char * ret = "hello world";
    return ret;
    }
    He would have an immediate memory problem: char * points to a piece of memory which was owned by the function. So after the function is called the memory containing the string is freed.

    The C-way to solve this problem is to use the heap. Which works - however one has to carefully manage the heap now, remembering to free the returned array:
    char * myfun() {
    char* ret = new char[12];
    return ret;
    }
    Gamemaker won't free the array for you, so if you wish to use the heap you'll have to create a specific "free" function. And make sure that the free function is called each time after the function returning the array.
    C++ programmers prefer to not use character arrays in such a case, and simply return a std::string object. - However gamemaker can't handle non primitive objects. So this can't be used either.

    The easiest way is to simply use a globalvariable to "hold" the data. (let's call it RetString for now) - As the scope of RetString is global, it won't go out of scope unless the dll is freed. And as there is just a single variable there's no possible memory leak. Use the c_str() member function to get the internal character array of the std::string. So the code would look like:
    std::string RetString; //outside function scope, global defined function.
    GMEXPORT const char * SampleFunctionCharArrays(char * a, char * b) {
    std::string first(a);
    std::string second(b);
    
    RetString = first + second;
    return RetString.c_str();
    }
    The only problem with this is that RetString is not thread safe, so you can't make threaded calls to functions that return strings. (If gamemaker ever supports threads, post a question about it and I'll give a method which is thread safe).
    the /tutorial_return/ part of the included zip contains examples with both types of return types.

    Pointers, handles & objects
    In many, many applications functions aren't so-called "monoliths". A function most of the time doesn't stand on it's own. Many times you have a function that first initializes an objects.. Than 10s of functions that will adapt & change the initialized object. And then a few functions that will read the object. The following sections will use a sample class, which should be defined as a seperate header file:
    //SampleClass.h
    #pragma once
    
    class SampleClass {
    public:
    SampleClass()
    {
    }
    void SetVals(double a, double b) {
    FirstVal = a;
    SecondVal = b;
    }
    double Multiply() {
    return FirstVal * SecondVal;
    }
    double Sum() {
    return FirstVal + SecondVal;
    }
    private:
    double FirstVal;
    double SecondVal;
    };
    Even gamemaker already does those things: think about datastructures or particles.
    The syntax is always like this, and it is good practice to use the same syntax for your own dlls/engines:
    -initialize function returns a handle
    -Other functions take as first argument this handle.

    Now the question is: what to use as a "handle". - A first and easy answer would be "a pointer". However after saying that you should immediatelly think: "but gamemaker can only support character arrays or doubles as return value". So you would have to start thinking about converting a pointer to a double. - Which isn't really recommended, nor considered good practice in a statically typed language such as C++. A better way is to prevent pointers. Below 3 manners to describe this will be presented. First I present a manner which prevents the whole pointer use, which is most compatible with standard C++. And I'll describe 2 ways you *can* use pointers. (as those are slightly faster and require much less setup/are much easier to understand).

    Circumventing the need for pointers
    This method is very recommended, espcially as all other methods are officially undefined behaviour. (Heck when discussing it with people who have years of C++ experience I won a bet whether the other methods actually work).
    Spoiler


    Using simple pointers
    Spoiler


    Using pointers & memcpy
    Spoiler

    With this you should be able to create your whole advanced DLLS, manage memory & do anything you wish in DLLS.

    Part 4 - Building the GameMaker programmers API
    For now The gamemaker part has been taken for granted, the included gamemaker files were just used. This part will look into the gamemaker parts of dlls. Some generally accepted "standard" will be discussed. There are some differences between GM 8.1 & GM:studio; when the difference is important a note will be made and you will see [GMS] or [GM81] around it.
    First of all realize that one can only create an API if one also knows what is INSIDE the dll, how everything should be called and what the limitations are. In other words: you have to have a documentation, or source code.

    Now for gamemaker there are basically three function of importance: external_define, external_call, and external_free.
    external_define() is used to define a "function", you have to specify how the function works with that. external_call is then used to execute this function. And external_free is finally used to free the data used by the DLL.

    When one uses DLL's it is best practice to leave the DLL in the main executable folder, as to keep all executing code together in a place. Though in very large games one might create a "system" subfolder or something. [GM81]
    Note however that from GM:STUDIO onwards it is hard, near impossible to refer to the executing folder when testing the game. As such for GM:Studio the fail safe manner is to include the file. (at the resource includes simply include the dll). Of course if you build dlls for others to use you should consider making it an extension, though building an extension is outside the scope of this tutorial (it starts with the same steps described here). [GMS]


    external_define
    As said the external_define function is used to "tell" gamemaker that the dll you create has a certain function, the exact syntax is:
    external_define(dllname, functionname, calling_convention, return_type, argument_number, arg1_type, arg2_type...)
    dllname is simply the name of the dll you call (can also be a relative path). The dllhost windows service will then lookup this name inside the application folder, and if it isn't found there in the system folders.
    functionname is the name of the function inside the dll. Please consider once again how name mangling works, about extern "C", and the problem with stdcall.
    calling_convention is eitehr dll_cdecl or dll_stdcall. It is decided by your dll, and you should use the calling choose there (normally dll_cdecl). Notice that if you chose dll_stdcall, you will have to take care of the naming convention. (prefix _ & postfix @ + argument size in bytes).
    return_type is the return type of your dll, once again make sure it matches the function. It can be either ty_real or ty_string, which corresponds with either doubles or character arrays resp.
    argument_number is simply the number of arguments your function takes.
    arg1_type...argN_type is for each argument the type your function takes (ty_real or ty_string).

    This command returns a number which should be used as "index" for external_call.

    The very first call to external_define is (as said) special: the dllmain function will also be invoked with as reason DLL_PROCESS_ATTACH, look it up at the start of the tutorial.

    external_call
    external_call executes a function you previously defined using external_define. The first argument is hence the value returned by the external_define option. The following functions are arguments which have to be passed to the dll.


    external_free
    External free frees all "data" from the dll. This function will free all memory, and removes all functions (so they have to be redefined). Recall that if your dll is unloaded during external_free, the dllmain function will be called. With as reason DLL_PROCES_DETACH, and the 3rd argument will be non NULL.

    Best practices
    Gamemaker is very forgiving as language, so it is hard to make it fail. However that doesn't mean there aren't good & bad ways to do something. Especially with DLLs.
    First of all, never ever constantly redefine a function (and free it) when you need it. Secondly, it is a terrible habit to expose external_call to the user of your engine (even yourself at another time). Always wrap external_calls inside a script.

    Basically it means each dll comes with an gmres (or other resource) file:
    • It should contain an "init" function, where all functions are defined. Best practice is to store the functions in global variables - if you write an engine prefix those global variables with your engine's. An example:
      globalvar InitFn, DeleteFn, SetFn, MultiplyFn, SumFn;
      
      InitFn = external_define("tutorial_class.dll", "InitializeClass", dll_cdecl, ty_real, 0);
      DeleteFn = external_define("tutorial_class.dll", "DeleteClass", dll_cdecl, ty_real, 1, ty_real);
      SetFn = external_define("tutorial_class.dll", "SetValues", dll_cdecl, ty_real, 3, ty_real, ty_real, ty_real);
      MultiplyFn = external_define("tutorial_class.dll", "Multiply", dll_cdecl, ty_real, 1, ty_real);
      SumFn = external_define("tutorial_class.dll", "Sum", dll_cdecl, ty_real, 1, ty_real);
      Better would've been if I prefixed the globalvars to indicate the engine I'm creating.
    • Each "dll-function" should have it's own script. These scripts should be called so external_call doesn't have to be called. As the functions aren't displayed in the help-part of gamemaker, you will have to give some help inside the scripts. So work on a good header format which displays at least those things: -The arguments should be explained, the returned value should be explained and finally side effects/limitations should be explained-.
    • External free is a dubious thing to use. First of all, using it when ending a game is considered "bad practice" in windows: as windows will free dlls loaded by your application anyways. However secondly remember what it does: it unloads all functions. However it doesn't give any indication to the globalvars you used to index functions. The globalvars aren't freed either. So you're left with a lot of indexes pointing towards nothing.
      The question hence becomes: do you wish to support "unloading & reloading" the dll during the game? - If you really have a good reason that a dll should be unloaded halfway, be sure to implement a "free" script. If however the game doesn't make sense without the dll loaded, don't implement it(NOTE 1).
    • When your dll works and your are now developing your game, it is important to be cautious on how you terminate your game when testing it. All you developers out there have run into trouble while programming a game, errors creep in and are eventually reported through the error window. Such errors as unknown variable x or array out of bound... It is important to note that when you have a dll loaded in memory, it is best to try to exit the game normally. So when you get the error dialog box, try to ignore the error until the game continues and then hit the ESC key to quit. There has been reports on erroneous dll related errors being reported when the functions are defined after an improper shut down of the game. This will limit the problem
    • Document your interface! Your work may be useless if there is no documentation on how to use the dll so document how each function works, include relationships with other functions and provide simple 3 liner example of how each function works. This is best to do while you write your c/c++ code while you are designing your interface, document your functions in the c++ source and move the comments to the GM script when defining the GML interface or in the help file if you plan to make a gm extension.
    NOTE 1:
    • That said, there are a few pointers for loading and unloading, the best place to load a dll is in a empty boot room (first room). A room only visited when the game starts (or is restarted). In such room you would drop a persistent Controller object. This object will follow you throughout the game in every room. You put the dll init function in the Game Start event of that object, followed by a room_goto_next() call. In the Game End event, there you would free the dll or call the un_init() function provided if any. The method ensures that no object will access the dll when not initialized, which can happen if you init the dll in the create of one object and use the dll features in the create of another object in the same room. Since the dll is loaded in the boot room before any of your game code executes, the functions will be defined and ready to use in the real game room.
    • The Game End is captured by the persistent object since it follows you. This is useful for games that call game_restart() or when you hit the restart menu in the debug window.
    Visual studio developing with Gamemaker 8.1 (and earlier)
    The following section is completely pointed at visual studio, and hence hidden from normal view. It explains what I figured as a very easy way to program a test case. The ability to test dlls using microsoft's debugging environment.
    Spoiler


    Visual studio developing with Gamemaker studio
    The following section is completely pointed at visual studio, and hence hidden from normal view. It explains what I figured as a very easy way to program a test case. The ability to test dlls using microsoft's debugging environment. This section also uses GM:Studio, as studio has some differences (in filesystem handling) that are of importance for GM. It is mostly a copy of previous section with some differences.
    Spoiler






    Good luck with writing your dll, if you have any questions feel free to ask them as usual smile.gif.


    Search Tags
    • GMCTUTORIAL
    • GMCDLL

  • 20

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#2 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 28 November 2011 - 03:51 PM

Original Tutorial
Spoiler

Edited by icuurd12b42, 19 September 2015 - 10:44 PM.

  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#3 zehevi

zehevi

    GMC Member

  • GMC Member
  • 746 posts
  • Version:GM:Studio

Posted 29 November 2011 - 02:22 AM

This tutorial is very useful and is very well explained with details.

Many thanks for this one. :thumbsup:
  • 0
Posted Image

An MMO RTS/RPG hybrid in development.


#4 NicharCZ

NicharCZ

    GMC Member

  • GMC Member
  • 10 posts
  • Version:GM8

Posted 12 January 2012 - 04:51 PM

Hello there,
tutorial is fine, but I have a problem. In debugging VS2010 shows me this:

1>------ Build started: Project: tutorial_class, Configuration: Debug Win32 ------
1>  main.cpp
1>     Creating library F:\Projects\My DLL's\Tutorials\tutorial_class\C++\Debug\tutorial_class.lib and object F:\Projects\My DLL's\Tutorials\tutorial_class\C++\Debug\tutorial_class.exp
1>     Creating library F:\Projects\My DLL's\Tutorials\tutorial_class\C++\Debug\tutorial_class.lib and object F:\Projects\My DLL's\Tutorials\tutorial_class\C++\Debug\tutorial_class.exp
1>  tutorial_class.vcxproj -> F:\Projects\My DLL's\Tutorials\tutorial_class\C++\Debug\tutorial_class.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

in one of your tutorials..

Would somebody help me to solve this? I really want to create my own DLL and with this error it is impossible. Please, step-by-step tutorial. Thanks a lot!

I've tried to find something about: "Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped". But no solution was there..

Edited by NicharCZ, 12 January 2012 - 04:55 PM.

  • 0

My games: The Scarecrow

 


#5 Guest_TamoNekiTipo_*

Guest_TamoNekiTipo_*
  • Guests

Posted 12 January 2012 - 05:30 PM

Good enough.
Though I probably won't use this info much...
I'm still a noob in C++ <_<

#6 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 12 January 2012 - 06:27 PM

Hello there,
tutorial is fine, but I have a problem. In debugging VS2010 shows me this:

1>------ Build started: Project: tutorial_class, Configuration: Debug Win32 ------
1>  main.cpp
1>     Creating library F:\Projects\My DLL's\Tutorials\tutorial_class\C++\Debug\tutorial_class.lib and object F:\Projects\My DLL's\Tutorials\tutorial_class\C++\Debug\tutorial_class.exp
1>     Creating library F:\Projects\My DLL's\Tutorials\tutorial_class\C++\Debug\tutorial_class.lib and object F:\Projects\My DLL's\Tutorials\tutorial_class\C++\Debug\tutorial_class.exp
1>  tutorial_class.vcxproj -> F:\Projects\My DLL's\Tutorials\tutorial_class\C++\Debug\tutorial_class.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

in one of your tutorials..

Would somebody help me to solve this? I really want to create my own DLL and with this error it is impossible. Please, step-by-step tutorial. Thanks a lot!

I've tried to find something about: "Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped". But no solution was there..


That's not an error, that is a Successfully Compiled message, if it said 1 or more Failed then that would be a problem
  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#7 NicharCZ

NicharCZ

    GMC Member

  • GMC Member
  • 10 posts
  • Version:GM8

Posted 12 January 2012 - 08:14 PM

That's not an error, that is a Successfully Compiled message, if it said 1 or more Failed then that would be a problem


Ok, I know.
But what should I do?

Edited by NicharCZ, 12 January 2012 - 08:27 PM.

  • 0

My games: The Scarecrow

 


#8 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 13 January 2012 - 01:31 AM

That's not an error, that is a Successfully Compiled message, if it said 1 or more Failed then that would be a problem


Ok, I know.
But what should I do?


grab the dll and start using it
  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#9 NicharCZ

NicharCZ

    GMC Member

  • GMC Member
  • 10 posts
  • Version:GM8

Posted 13 January 2012 - 08:51 AM

Oh, solved, thanks a lot! :) I didn't know that is so easy :D I'm sorry
  • 0

My games: The Scarecrow

 


#10 Debels

Debels

    GMC Member

  • GMC Member
  • 3029 posts
  • Version:GM:Studio

Posted 14 July 2012 - 02:35 PM

Going to try and make a dll for GM with this code :)
  • 0

"Give a man a fish, and you feed him for a day; show him how to catch fish, and you feed him for a lifetime."

(Chinese axiom)


#11 zehevi

zehevi

    GMC Member

  • GMC Member
  • 746 posts
  • Version:GM:Studio

Posted 27 August 2012 - 01:04 AM

I'm having hard time understanding how to use a DLL for other then mathematical functions.
I'm giving my DLL variables, the DLL then calculate and return a new value,
But I want to extend GM's functionality or speed up slow functions.
Google led me to classes, and right there - I went lost.

Could you explain what it does and if it really is the way to "extend" GM's fanctionality, or atleast lead me to it?

Sorry if it was unclear.
Thanks, Zehevi.
  • 0
Posted Image

An MMO RTS/RPG hybrid in development.


#12 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 27 August 2012 - 02:52 AM

I'm having hard time understanding how to use a DLL for other then mathematical functions.
I'm giving my DLL variables, the DLL then calculate and return a new value,
But I want to extend GM's functionality or speed up slow functions.
Google led me to classes, and right there - I went lost.

Could you explain what it does and if it really is the way to "extend" GM's fanctionality, or atleast lead me to it?

Sorry if it was unclear.
Thanks, Zehevi.


You dont need a class.

from post 2, hidden original tutorial
extern "C" {

//Example passing a number
gmexport double SampleFunctionNumber(double count)
{
        //Loop to count
        //Note the cast so the compiler does not show warning, casts are resolved at compile time, 
        //they have little effect at run time
        char formated[20];
        MessageBoxA(GetActiveWindow(),"","SampleFunctionNumber"
, MB_ICONINFORMATION|MB_OK);
        for(int i = 0; i<(int)count; i++)
        {
                wsprintf(formated,"count %d",i);
                MessageBoxA(GetActiveWindow(),formated,"SampleFunctionNumber"
, MB_ICONINFORMATION|MB_OK);
        }
        return (double) 1;
}

//example passing string
gmexport double SampleFunctionString(LPCSTR string)
{
        //Show a message. GetActiveWindow always returns GM's Main window.
        return (double) MessageBoxA(GetActiveWindow(),string,"SampleFunctionString"
, MB_ICONINFORMATION|MB_OKCANCEL);
}

}

  • 1

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#13 zehevi

zehevi

    GMC Member

  • GMC Member
  • 746 posts
  • Version:GM:Studio

Posted 29 August 2012 - 06:13 AM

You dont need a class.

from post 2, hidden original tutorial

extern "C" {

//Example passing a number
gmexport double SampleFunctionNumber(double count)
{
        //Loop to count
        //Note the cast so the compiler does not show warning, casts are resolved at compile time, 
        //they have little effect at run time
        char formated[20];
        MessageBoxA(GetActiveWindow(),"","SampleFunctionNumber"
, MB_ICONINFORMATION|MB_OK);
        for(int i = 0; i<(int)count; i++)
        {
                wsprintf(formated,"count %d",i);
                MessageBoxA(GetActiveWindow(),formated,"SampleFunctionNumber"
, MB_ICONINFORMATION|MB_OK);
        }
        return (double) 1;
}

//example passing string
gmexport double SampleFunctionString(LPCSTR string)
{
        //Show a message. GetActiveWindow always returns GM's Main window.
        return (double) MessageBoxA(GetActiveWindow(),string,"SampleFunctionString"
, MB_ICONINFORMATION|MB_OKCANCEL);
}

}


Thanks Icuurd.
This is not the answer I expected to receive but, I do understand it.
Since GM cannot pass resources and object names to the DLL (DLL wouldn't know what to do with it?),
I just gonna have to satisfy with this.

After thinking this over, how do you handle graphics through the DLL?
The DLL is suppose to call, for example, OpenGL functions and communicate directly
with the graphics card and not back to the GM? (like GM>DLL>GPU and not GM>DLL>GM>GPU)

Oh 1 last question that is probably the most important one,
how can I handle arrays?
Just declare them and the data would be saved as long as the DLL is running,
or the DLL cannot save data?

Edited by zehevi, 29 August 2012 - 06:23 AM.

  • 0
Posted Image

An MMO RTS/RPG hybrid in development.


#14 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 29 August 2012 - 07:11 AM

Thanks Icuurd.
This is not the answer I expected to receive but, I do understand it.
Since GM cannot pass resources and object names to the DLL (DLL wouldn't know what to do with it?),
I just gonna have to satisfy with this.

You can get GMAPI and you will be able to access GM functions from the dll. And you will be able to pass GM resources to the dll and you can do stuff with the resource through GMAPI, like say passing a sprite and you can draw it in a loop in a function you called in the draw event of an object. You dll wouljd need a drawFunc to be called by from the GM side.

After thinking this over, how do you handle graphics through the DLL?
The DLL is suppose to call, for example, OpenGL functions and communicate directly
with the graphics card and not back to the GM? (like GM>DLL>GPU and not GM>DLL>GM>GPU)

It's complicated to have the dll draw on the graphis card without interfering with GM's drawing. Again, GMAPI would allow you to draw in the GM world.

Oh 1 last question that is probably the most important one,
how can I handle arrays?
Just declare them and the data would be saved as long as the DLL is running,
or the DLL cannot save data?

You cant pass anything but a double or a string to the dll. so you're sortof screwed. However, if you get GMAPI, you can communicate large amount of data back a forth via a ds_list
  • 1

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#15 zehevi

zehevi

    GMC Member

  • GMC Member
  • 746 posts
  • Version:GM:Studio

Posted 29 August 2012 - 11:40 AM

Okay, so the answer to my problems is GMAPI.

But let me rephrase my last question: If I declare a variable in the DLL enviroment, will it's value
exist as long as the DLL is "attached" to GM, or will the variable be destroyed once the DLL return the value (or simple end the case).
(aka: is the memory used for the DLL is reserved as long as GM is holding the DLL?).

Thanks again Icuurd.
  • 0
Posted Image

An MMO RTS/RPG hybrid in development.


#16 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 29 August 2012 - 04:39 PM

Okay, so the answer to my problems is GMAPI.

But let me rephrase my last question: If I declare a variable in the DLL enviroment, will it's value
exist as long as the DLL is "attached" to GM, or will the variable be destroyed once the DLL return the value (or simple end the case).
(aka: is the memory used for the DLL is reserved as long as GM is holding the DLL?).

Thanks again Icuurd.


Variable scope varies. it depends where you declared the variable in the c++ project

int globalVariable = 10
eport souble func()
{
int localSope = 11;

}

Of course pointers allocated with new or malloc needs to be freed manually later on.
memory should stay allocated until the program quits. Pretty sure even if you unload the dll, the memory is only freed when the program quits. It's part of the OS to rid any memory leaked by the program.
  • 1

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#17 zehevi

zehevi

    GMC Member

  • GMC Member
  • 746 posts
  • Version:GM:Studio

Posted 31 August 2012 - 02:29 PM

That was really helpful. Thanks again!
  • 0
Posted Image

An MMO RTS/RPG hybrid in development.


#18 markmd76

markmd76

    GMC Member

  • GMC Member
  • 121 posts
  • Version:GM:Studio

Posted 22 December 2012 - 08:29 AM

Should this work in GM Studio? I ask as I have tried it and always get a zero returned following the example. I even tried importing the tutorial2 source provided and that too returns a zero.
  • 0

Tia_X_banner.jpg


#19 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 22 December 2012 - 06:16 PM

Should this work in GM Studio? I ask as I have tried it and always get a zero returned following the example. I even tried importing the tutorial2 source provided and that too returns a zero.


DLLs are still available in studio. you need to change the type in the GM definition since the tutorial was written at the time for GM6 through 8.1 and those version had a bug in the external_define which forced us to use the wrong export type...
  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#20 paul23

paul23

    GMC Member

  • Global Moderators
  • 4147 posts
  • Version:GM:Studio

Posted 23 December 2012 - 01:09 AM

Should this work in GM Studio? I ask as I have tried it and always get a zero returned following the example. I even tried importing the tutorial2 source provided and that too returns a zero.


DLLs are still available in studio. you need to change the type in the GM definition since the tutorial was written at the time for GM6 through 8.1 and those version had a bug in the external_define which forced us to use the wrong export type...


I hope you're referring to the old-tutorial here? As what the dll says still holds true: if you make a dll that uses cdecl as calling convention (default for C-style functions). GM should also have that in its definition..

calling_convention is eitehr dll_cdecl or dll_stdcall. It is decided by your dll, and you should use the calling choose there (normally dll_cdecl).


This line of the tutorial indicates the choice - normally dll_cdecl, unless you explicitly chose otherwise.

EDIT: I did some extensive testing and the return example indeed shows errors. Though I already found the culprit: some kind of silly stupidity on my part.. I honestly forgot the word "return" in the scripts. Previously gamemaker had a bug where if you forgot the return statement in a script, it would return the last calculated value.

So change the scripts "String" to:
return external_call(StringFn, argument0, argument1);
and "Real" to:
return external_call(RealFn, argument0, argument1);

I'm too tired to look through all tutorial files, will do somewhere this year (hopefully :P). But quite amazing you're the first to find this bug!
  • 0

#21 markmd76

markmd76

    GMC Member

  • GMC Member
  • 121 posts
  • Version:GM:Studio

Posted 23 December 2012 - 07:55 AM

Thanks for the assistance, I have now been able to get it all working :D
  • 0

Tia_X_banner.jpg


#22 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 23 December 2012 - 08:10 AM

Should this work in GM Studio? I ask as I have tried it and always get a zero returned following the example. I even tried importing the tutorial2 source provided and that too returns a zero.


DLLs are still available in studio. you need to change the type in the GM definition since the tutorial was written at the time for GM6 through 8.1 and those version had a bug in the external_define which forced us to use the wrong export type...


I hope you're referring to the old-tutorial here? As what the dll says still holds true: if you make a dll that uses cdecl as calling convention (default for C-style functions). GM should also have that in its definition..

calling_convention is eitehr dll_cdecl or dll_stdcall. It is decided by your dll, and you should use the calling choose there (normally dll_cdecl).


Because I had referenced to old tut for a concept. The user was trying to use the the old stuff.

This line of the tutorial indicates the choice - normally dll_cdecl, unless you explicitly chose otherwise.

EDIT: I did some extensive testing and the return example indeed shows errors. Though I already found the culprit: some kind of silly stupidity on my part.. I honestly forgot the word "return" in the scripts. Previously gamemaker had a bug where if you forgot the return statement in a script, it would return the last calculated value.

So change the scripts "String" to:

return external_call(StringFn, argument0, argument1);
and "Real" to:
return external_call(RealFn, argument0, argument1);

I'm too tired to look through all tutorial files, will do somewhere this year (hopefully :P/>/>). But quite amazing you're the first to find this bug!


I'm glad someone is up keeping this topic.

Thanks paul
  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#23 paul23

paul23

    GMC Member

  • Global Moderators
  • 4147 posts
  • Version:GM:Studio

Posted 10 January 2013 - 04:42 PM

Just to inform everyone: I've update the tutorial to also support GM:studio.

All examples work in GM:studio now & they have studio project files added to them (The GMS folders in the zip directory). Also added a small part on the change between GM8.1 & studio. I'll extend that once I have more time.
  • 1

#24 Debels

Debels

    GMC Member

  • GMC Member
  • 3029 posts
  • Version:GM:Studio

Posted 10 January 2013 - 06:51 PM

Would GM:Studios support C# dll's?
  • 0

"Give a man a fish, and you feed him for a day; show him how to catch fish, and you feed him for a lifetime."

(Chinese axiom)


#25 paul23

paul23

    GMC Member

  • Global Moderators
  • 4147 posts
  • Version:GM:Studio

Posted 10 January 2013 - 11:33 PM

Would GM:Studios support C# dll's?

No... Well unless you write a wrapper dll using C++/CLI or something similar (But that works for all version of GM from 4.1 onwards). But than again the interface would still be the simplistic C-interface..
  • 0

#26 CountVlad

CountVlad

    GMC Member

  • GMC Member
  • 204 posts
  • Version:GM:Studio

Posted 17 September 2013 - 07:48 PM

my gm:s version is up to date.

i am in the work of making a win api dll because the last dll, well, atleast of what ive seen, that was released to have the win api capacity was hobels, and it wont work on gm:s, by the time i try it on game maker and use the functions on my dll to my game i get an error of:

In Script InitDLL at line 4 : unknown function or script external_define
In Script Foo at line 2 : unknown function or script external_call

but, those functions are not obsolete. what is wrong? is this a bug?

 

edit:

[SOLVED]-i solved it myself.

 

edit: i have a new problem,

 
___________________________________________
############################################################################################
ERROR in
action number 1
of Create Event
for object objDLL:


Error defining an external function.
 at gml_Script_InitDLL (line 2) - InitFn = external_define("tutorial_class.dll",  "InitializeClass", dll_cdecl, ty_real, 0);
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_InitDLL (line 0)
called from - gml_Object_objDLL_Create_0 (line 1) - globalvar InitFn, DeleteFn, SetFn, MultiplyFn, SumFn;

this thing showed up when i run the tutorial_class(the first tutorial i opened). i dont know how to diagnose it. please help.


Edited by CountVlad, 17 September 2013 - 08:05 PM.

  • 0

go to CountVlad's Site now!

 

need UI for your game? click image on spoiler to link you to my UI extension.

 

Spoiler

#27 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 17 September 2013 - 09:09 PM

it the dll packaged with the project, in the Includes Files?
  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#28 CountVlad

CountVlad

    GMC Member

  • GMC Member
  • 204 posts
  • Version:GM:Studio

Posted 18 September 2013 - 03:00 AM

what?

it the dll packaged with the project, in the Includes Files? 

 

it? or is?

 

yes it is. i know how to debug errors, but this one, i cant since it is with a dll


  • 0

go to CountVlad's Site now!

 

need UI for your game? click image on spoiler to link you to my UI extension.

 

Spoiler

#29 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 18 September 2013 - 01:51 PM

what's your source for the dll?

And of course it what is ^__^
  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#30 CountVlad

CountVlad

    GMC Member

  • GMC Member
  • 204 posts
  • Version:GM:Studio

Posted 19 September 2013 - 03:24 PM

i got the dll from this forum post.


  • 0

go to CountVlad's Site now!

 

need UI for your game? click image on spoiler to link you to my UI extension.

 

Spoiler

#31 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 19 September 2013 - 10:34 PM

The error is not in the dll but gm trying to link to it

probably causes
1) the dll is not in the application folder, in studio, that mean not in the Included Files.
make sure the dll is in the Datafiles folder in the gmx directory AS WELL AS in the Studio Included Files branch in the UI. Copy the dll to the gmx folder FIRST and include it for there in the studio UI (AKA delete the existing one from the UI and drag drop the file from the Datafiles Folder on the ui) else the file will not be included properly
2) the dll is a debug compile. Use the release compile
3) The functions you define use return type or parameter type other than LPSTR (aka char *) or double
4) you made a mistake with the argument count or the argument list in the external_define call in GM or the type (cdcl)
5) your exported function are missing the GMEXPORT declaration

GMEXPORT double SampleFunction(double a, double b ) {
return a * b;
}

Edited by icuurd12b42, 19 September 2013 - 10:35 PM.

  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#32 CountVlad

CountVlad

    GMC Member

  • GMC Member
  • 204 posts
  • Version:GM:Studio

Posted 20 September 2013 - 01:33 AM

The error is not in the dll but gm trying to link to it

probably causes
1) the dll is not in the application folder, in studio, that mean not in the Included Files.
make sure the dll is in the Datafiles folder in the gmx directory AS WELL AS in the Studio Included Files branch in the UI. Copy the dll to the gmx folder FIRST and include it for there in the studio UI (AKA delete the existing one from the UI and drag drop the file from the Datafiles Folder on the ui) else the file will not be included properly
2) the dll is a debug compile. Use the release compile
3) The functions you define use return type or parameter type other than LPSTR (aka char *) or double
4) you made a mistake with the argument count or the argument list in the external_define call in GM or the type (cdcl)
5) your exported function are missing the GMEXPORT declaration

GMEXPORT double SampleFunction(double a, double b ) {
return a * b;
}

 

i tried the 1st and 2nd one, nothing works.

i wouldn't give 3,4,&,5 a try becaause its your tutorial files.


  • 0

go to CountVlad's Site now!

 

need UI for your game? click image on spoiler to link you to my UI extension.

 

Spoiler

#33 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 20 September 2013 - 03:23 AM

good luck. my tutorial is actually on post #2
  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#34 paul23

paul23

    GMC Member

  • Global Moderators
  • 4147 posts
  • Version:GM:Studio

Posted 29 September 2013 - 01:22 PM

Uh @ countvlad: I don't have the newest version yet (or at least, have time to play around with it). But it sounds like DLLs are simply no longer supported in GM with the compiler options. What did you do to solve the first problem?


  • 0

#35 CountVlad

CountVlad

    GMC Member

  • GMC Member
  • 204 posts
  • Version:GM:Studio

Posted 30 September 2013 - 02:49 PM

i was not able to solve the problem
  • 0

go to CountVlad's Site now!

 

need UI for your game? click image on spoiler to link you to my UI extension.

 

Spoiler

#36 paul23

paul23

    GMC Member

  • Global Moderators
  • 4147 posts
  • Version:GM:Studio

Posted 30 September 2013 - 06:19 PM

The one where you got the following errors:
 
In Script InitDLL at line 4 : unknown function or script external_define
In Script Foo at line 2 : unknown function or script external_call


Also: made you sure to unzip everything into a folder and THEN open it? not open it from the zipped directory.
  • 0

#37 CountVlad

CountVlad

    GMC Member

  • GMC Member
  • 204 posts
  • Version:GM:Studio

Posted 30 September 2013 - 06:53 PM

yup. i tried other dlls and they worked. dont know why this doesn't


  • 0

go to CountVlad's Site now!

 

need UI for your game? click image on spoiler to link you to my UI extension.

 

Spoiler

#38 Crocodarrel

Crocodarrel

    GMC Member

  • New Member
  • 13 posts
  • Version:GM:Studio

Posted 08 December 2013 - 03:28 AM

Thanks for the tutorial, but your post is a bit munged by emoticons. Any chance of fixing that?


  • 0

#39 grimdayz

grimdayz

    a.t.t.i.c.

  • GMC Member
  • 1207 posts
  • Version:GM:Studio

Posted 29 December 2013 - 08:56 PM

I was having the same problem as CountVlad. I solved it by adding the following to my linker settings in Code::Blocks:

-static

Edited by grimdayz, 29 December 2013 - 08:59 PM.

  • 0

#40 CookWeR

CookWeR

    GMC Member

  • New Member
  • 2 posts
  • Version:GM:Studio

Posted 29 December 2013 - 09:16 PM

 

my gm:s version is up to date.

i am in the work of making a win api dll because the last dll, well, atleast of what ive seen, that was released to have the win api capacity was hobels, and it wont work on gm:s, by the time i try it on game maker and use the functions on my dll to my game i get an error of:

In Script InitDLL at line 4 : unknown function or script external_define
In Script Foo at line 2 : unknown function or script external_call

but, those functions are not obsolete. what is wrong? is this a bug?

 

edit:

[SOLVED]-i solved it myself.

 

edit: i have a new problem,


I have the same problem. How did you solve it?


  • 0

#41 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 30 December 2013 - 12:26 AM

my gm:s version is up to date.
i am in the work of making a win api dll because the last dll, well, atleast of what ive seen, that was released to have the win api capacity was hobels, and it wont work on gm:s, by the time i try it on game maker and use the functions on my dll to my game i get an error of:

In Script InitDLL at line 4 : unknown function or script external_define
In Script Foo at line 2 : unknown function or script external_call
but, those functions are not obsolete. what is wrong? is this a bug?
 
edit:
[SOLVED]-i solved it myself.
 
edit: i have a new problem,


I have the same problem. How did you solve it?


You got the steam version of studio. Steam would not allow Studio to be sold on there with dll features enabled because steam does not trust it's own community of programmers.

Get the non steam version of studio from yoyo directly.
  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#42 CookWeR

CookWeR

    GMC Member

  • New Member
  • 2 posts
  • Version:GM:Studio

Posted 19 January 2014 - 06:14 PM

 

 

my gm:s version is up to date.
i am in the work of making a win api dll because the last dll, well, atleast of what ive seen, that was released to have the win api capacity was hobels, and it wont work on gm:s, by the time i try it on game maker and use the functions on my dll to my game i get an error of:
 

In Script InitDLL at line 4 : unknown function or script external_define
In Script Foo at line 2 : unknown function or script external_call
but, those functions are not obsolete. what is wrong? is this a bug?
 
edit:
[SOLVED]-i solved it myself.
 
edit: i have a new problem,


I have the same problem. How did you solve it?

 


You got the steam version of studio. Steam would not allow Studio to be sold on there with dll features enabled because steam does not trust it's own community of programmers.

Get the non steam version of studio from yoyo directly.

 

I need to buy it again?


  • 0

#43 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 20 January 2014 - 12:22 AM

I need to buy it again?

 

 

 

Ask Yoyo


  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#44 Yal

Yal

    Even though the GMC may be gone, our love will prevail eternally

  • Global Moderators
  • 11774 posts
  • Version:GM:Studio

Posted 01 July 2015 - 03:01 PM

This tutorial seems pretty interesting, I might have to interface to an API in one of my projects and reading this made it feel a slight bit harder :3

 

(Which is probably a good thing, so that I don't make stupid mistakes from oversimplifying)


  • 0

- The above is my personal opinion and in no way representative of Yoyogames or the GMC, except when explicitly stated -

 

Open this spoiler for my games:

Spoiler

Some useful game engines, music and other resources at affordable prices:

My collection of game resources at itch.io

 

New user? Can't draw but want to look unique? You can request a new avatar in this thread!


#45 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 01 July 2015 - 05:52 PM

This tutorial seems pretty interesting, I might have to interface to an API in one of my projects and reading this made it feel a slight bit harder :3
 
(Which is probably a good thing, so that I don't make stupid mistakes from oversimplifying)


Read Post 2 first then Post 1. it may be easier to grasp
  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#46 BPzeBanshee

BPzeBanshee

    GMC Member

  • GMC Member
  • 24 posts
  • Version:Unknown

Posted 13 January 2016 - 05:56 AM

Absolutely none of these examples work with Code::Blocks and I'm not sure why. On the testcase tutorial the existing DLL spat a bunch of errors regarding missing DLLs, and attempting to compile it was trying to make an EXE instead of a DLL and "undefined reference to WinMain16" even though everything was in place. Yet the same DLL code on another separate app in a different folder works fine. Very frustrating stuff.

 

Is there any tutorials of this calibre that are actually tailored for Code::Blocks or straight GCC/G++ commandline instead of Visual C++? It seems to be adding stuff in that I'm clearly missing and I've been banging my head against the wall for about three days straight trying to figure it all out.


  • 0

#47 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 13 January 2016 - 10:08 AM

Absolutely none of these examples work with Code::Blocks and I'm not sure why. On the testcase tutorial the existing DLL spat a bunch of errors regarding missing DLLs, and attempting to compile it was trying to make an EXE instead of a DLL and "undefined reference to WinMain16" even though everything was in place. Yet the same DLL code on another separate app in a different folder works fine. Very frustrating stuff.
 
Is there any tutorials of this calibre that are actually tailored for Code::Blocks or straight GCC/G++ commandline instead of Visual C++? It seems to be adding stuff in that I'm clearly missing and I've been banging my head against the wall for about three days straight trying to figure it all out.


Hmm, post 2!!? Original tutorial explains the devc++ and code::block variant.

code::blocks
Make sure you installed with the code::block installation that has the gnu compiler packaged with it.

file->new->project
Category:Dynamic Link Library
Next
Next
in the Dynamic Library Properties, Use default, Default is the GNU compiler
Finish


you will have a bank Main.cpp and Main.h where you can add your includes as specified in the tutorial(s)

Edited by icuurd12b42, 13 January 2016 - 10:17 AM.

  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#48 BPzeBanshee

BPzeBanshee

    GMC Member

  • GMC Member
  • 24 posts
  • Version:Unknown

Posted 14 January 2016 - 01:50 PM

I didn't see anything in post 2 regarding Code::Blocks specifically per se, but when I created the new project as you described and then used the code that was in the clipboard rather than in the cpp_dll_tutorial download it seemed to work. The code looks way different but it's a start and I can learn from there. Cheers icurd!

EDIT: Oh, I also found that there's an import option to import from project files which might save time for the establishing of library/header locating! Helped with a few files anyway. Also of note the Projects tab in the Management section on the left is essential browsing to getting anything to work if you're dealing with headers and libraries in subfolders. Clearly I needed a break when looking into this stuff. :/

tutorial_class in the download still doesn't work importing it that way though, errors out because apparently this:

unsigned int ind = unsigned int(i);

in code::blocks needs to be this instead:

unsigned int ind = (unsigned int)i;

and NULL apparently needs to be declared. I read that using 0 is an acceptable replacement but isn't the point of null that there is no data so checking for 0 instead of null would defeat the purpose of the null check?


Edited by BPzeBanshee, 14 January 2016 - 02:01 PM.

  • 0

#49 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 18181 posts
  • Version:GM:Studio

Posted 14 January 2016 - 03:21 PM

you need to include windows.h if you want that NULL and all other windowsy types like LPSTR, LPCSTR UINT INT LONG and so on.

not sure of the new type cast support, I dont use them myself (The first post was re-written/modernized by paul23). Pretty standard c++ stuff though. I'm surprised. Perhaps the context is not available if you have those inside the

extern "C" {
}

I think null is
define NULL ((void *) 0)
  • 0

gmcbanner.pnggmcbanner_tools.png

ICU Live Tutoring Through Slack or Skype | My Tools Page follow.png

I FRANTICALLY MADE MY 18000 POST TOPIC BEFORE MIKE ANNOUNCED A DELAY...
Now I'm squirming not to hit that reply button


#50 BPzeBanshee

BPzeBanshee

    GMC Member

  • GMC Member
  • 24 posts
  • Version:Unknown

Posted 15 January 2016 - 02:53 AM

That's the weird thing - I had windows.h included!

 

And now I go into the same project file today, set the 0s back to NULL and it works fine! I think I'm going mad. ;(


  • 0