• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Strewya

Unity
DLL question

13 posts in this topic

Hey community!

I have a question about DLLs, and whether what i'm trying to do is possible at all.

Here's my issue. I would like to have all of my rendering code packed away nicely in a DLL, to which i would link in my main project. However, i would also like to keep the rendering specific API linkage (D3D or OpenGL) also packed in that DLL, so my main project wouldn't have to worry about what rendering API is lying underneath.

Note that i'm not trying to use runtime API switching or anything, as right now i'm only working my way up to learning D3D9, and if (heavy emphasis) at any point i'd try supporting another API, i would build the project with different files. But i'd like it that i only needed to change the graphics classes in question (like, instead of having a LPDIRECT3DTEXTURE9 member it would be an GL_int). The main project would never use these API specific members, only the renderer itself would use them.

I know i could solve this by making an interface for every class that has any API specific code in its header, but i really don't need to have runtime polymorphism since i'm only using one API in a build. I was thinking about doing something with typedefs, but i'd still be adding the graphics classes headers into the main project, which would in turn try to include d3d9.h, which i'm hoping i don't have to link in the main project. Even if i never get to a point where i would try adding support for OpenGL, it'd still be nice if all d3d9 linking was contained in the renderer DLL.

So in short, i'm trying to:
1. link my renderer DLL into my main project
2. only link the d3d libs in the renderer DLL (EDIT: oh, and that includes the include/lib/source directories as well)
3. not have to link d3d in the main project
4. not use inheritance for any of the graphics classes, but still be able to use them in the main project (and not use any API specific calls on those classes, mostly just getters)

I hope i explained myself well enough to get some advice. Thanks in advance! smile.png Edited by Strewya
1

Share this post


Link to post
Share on other sites

I've done the whole renderer-in-a-runtime-swappable-dll-accessed-via-pure-virtual-interface thing in the past.

 

I can't be sure why you don't want to use interface inheritance, but I can say that if my engine were making so many calls to the renderer that the virtual function call overhead became a performance concern, I'd think I must be doing something very wrong.

 

2

Share this post


Link to post
Share on other sites

So in short, i'm trying to:
1. link my renderer DLL into my main project
2. only link the d3d libs in the renderer DLL (EDIT: oh, and that includes the include/lib/source directories as well)
3. not have to link d3d in the main project
4. not use inheritance for any of the graphics classes, but still be able to use them in the main project (and not use any API specific calls on those classes, mostly just getters)

I hope i explained myself well enough to get some advice. Thanks in advance! smile.png

If that is all, than use dx,ogl headers only in renderer definitions (cpp files) and never expose them to declarations of rendered classes. That is all that's needed to do. You will have to write a lot more code to recieve such an isolation with enough level of operatibility though. And when you do, watch out for optimization side, (avoid memory copying and other unneeded stuff).

2

Share this post


Link to post
Share on other sites

Thanks for the replies.

It seems like the last point is the troublemaker here, so i guess i'll drop it and go with interfaces. What i wanted to avoid is having to create an interface for each class that i'd put into the graphics dll, but i haven't made a list of what classes from the dll would actually be exposed outward. I thought i'd have to expose all the low level stuff (like vertex/index buffer, textures and such), but if i compose them into higher level concepts (like sprite, model etc), than i end up with just a few interfaces. Is this a good approach?

 

While i'm at it, i've got another question. If i use the interfaces to call the underlying concrete objects, that means that all of them have to be heap allocated, unless i use globals inside the dll (and i don't want to if i can help it)? Also, everything created within the dlls factory method should also be sent to the dll to destroy instead of destroying them manually, right? And lastly, the runtime switching, is that possible if i link the .lib and use the DLL for implementation, or do i need to use LoadLibrary and manually do the switching? I'm actually not sure if its even possible to change the DLL on the fly while the exe is running, as the DLL would be in use, right? And even if that's possible, how would the exe know to reload the DLL?

 

Again, thanks for the advice! :)

0

Share this post


Link to post
Share on other sites

I thought i'd have to expose all the low level stuff (like vertex/index buffer, textures and such), but if i compose them into higher level concepts (like sprite, model etc), than i end up with just a few interfaces. Is this a good approach?

Whichever approach is going to be easiest for you. There's no right or wrong way really.
 

While i'm at it, i've got another question. If i use the interfaces to call the underlying concrete objects, that means that all of them have to be heap allocated, unless i use globals inside the dll (and i don't want to if i can help it)?

Correct. Stack allocating a vertex buffer isn't the most intelligent approach ;)
 

Also, everything created within the dlls factory method should also be sent to the dll to destroy instead of destroying them manually, right?

You can call delete on the objects, but you WILL need a virtual destructor. I still prefer a destroy method myself, but that's just me.

And lastly, the runtime switching, is that possible if i link the .lib and use the DLL for implementation, or do i need to use LoadLibrary and manually do the switching?

Yes, you will need to use LoadLibrary (or dlopen for posix). *If* you have a pure virtual base class, then the minimum you'd need to faff around with is:

 

// plugin API

[source]

class Device
{
public:

   virtual ~Device() {}

};

 

extern "C"
{
typedef Device* (*createDeviceFunc)();

}

[/source]

 

// plugin Implementation

[source]
class MyDevice : public Device
{
public:
  MyDevice() {}
}:

 

extern "C"
{
__declspec(dllexport) Device* createDevice() { return new MyDevice; }

}

[/source]

// in your app

[source]

#include "PluginAPI.h"

 

createDeviceFunc createDevice = 0;
HMODULE plugin = 0;

Device* device = 0;

 

void loadPlugin(const char* dllname)

{

  plugin = LoadLibraryA( dllname );
  if(plugin)
  {
     createDevice = (createDeviceFunc)GetProcAddressA(plugin, "createDevice");

     if(createDevice)
    {

      device = createDevice();
    }
  }
}

// then somewhere in your startup code
loadPlugin("myGLRenderer.dll");

[/source]

I'm actually not sure if its even possible to change the DLL on the fly while the exe is running, as the DLL would be in use, right?

You'll need to make sure it's no longer in use, and then it can be unloaded safely.

[source]

void unloadPlugin()

{
  delete device; //< this must also delete all buffers, textures, etc
  device = 0;
  createDevice = 0;
  FreeLibrary(plugin);

}

[/source]

 

And even if that's possible, how would the exe know to reload the DLL?

You'll have to tell it to load the plugin again!

[source]
loadPlugin("myD3D11Renderer.dll");

[/source]
 

1

Share this post


Link to post
Share on other sites
What i wanted to avoid is having to create an interface for each class that i'd put into the graphics dll, but i haven't made a list of what classes from the dll would actually be exposed outward. I thought i'd have to expose all the low level stuff (like vertex/index buffer, textures and such), but if i compose them into higher level concepts (like sprite, model etc), than i end up with just a few interfaces. Is this a good approach?

Yes.  You should keep the renderer interface used by the rest of the engine as minimal and simple as possible. 

 

Also, everything created within the dlls factory method should also be sent to the dll to destroy instead of destroying them manually, right?

No.  Your dll will generally be compiled against the same memory manager as the rest of the engine (unless you do something to prevent it), and your engine is linked against the interface you expose from the dll, so generally, the engine can delete objects it gets from the dll.

 

That being said, code defined in the dll, including destructors and anything they call, can only be called while the dll is loaded.  So it's a bad idea for the renderer to be handing out objects implemented in the dll.

 

In my implementation, the engine only handled a single dll specific object - the renderer itself.  All other render related objects handled by the engine were defined outside of the dll.  They were written in terms of the renderer's interface.  All data resources with API specific formats were held within the renderer internally, and referenced externally by ID (so the resource could swap out when the renderer did, without breaking external references).

 

On a side note, this means that if you ever do decide to make your renderer hot-swappable, it'll need to do a little fancy footwork for the post-swap renderer to acquire all the API specific data resources corresponding to those which had been held by the pre-swap renderer.

 

I'm actually not sure if its even possible to change the DLL on the fly while the exe is running, as the DLL would be in use, right? And even if that's possible, how would the exe know to reload the DLL?

Yes, you can unload a dll.  It's up to you to make sure you don't use it before loading or after unloading it.

 

I'm not sure I understand the question - but the exe "knows" because you write it to know.  You unload one dll and load another when you see fit.

1

Share this post


Link to post
Share on other sites
I wasn't quite thinking when asking the hot-swap question, as in my mind i was referring to hot swapping the exact same DLL during runtime, which is impossible since you can't overwrite a file being in use. But hot-swapping to another DLL i do know what is needed, but it requires a lot of tech design and preparation in order to get right (mostly related to managing renderer specific resources when the swap occurs).

But i did figure that i'd need to have two sets of resource caches, one within the DLL itself which would manage the renderer specific resource, and one outside of the DLL which would manage ID references to the resources inside the DLL. And i like the ID referencing system because it allows for resource hot-loading, at least for the development phase. smile.png

However, that does mean writing two separate caches for the same resource type. I'm guessing it's possible to template it somehow, but that requires even more design biggrin.png

Btw, on a completely unrelated note to DLLs, but related to Direct3D itself, is there any "standard" (or a majority opinion) for using COM smart pointers? I'm not sure whether i should use the CComPtr (or whatever it's called, been a while since i read about them), or simply write my own wrapper class which would call AddRef() and Release() during copy ctor/operator=? It's a bit hard to find information on whether they should be used or not.

Thanks!
0

Share this post


Link to post
Share on other sites

Btw, on a completely unrelated note to DLLs, but related to Direct3D itself, is there any "standard" (or a majority opinion) for using COM smart pointers?

 

If DLL's are involved, I'd avoid smart pointers completely (personally speaking). If you *really* need that kind of thing, and it works for you, then using CComPtr will be better than the alternatives (i.e. boost et al).

0

Share this post


Link to post
Share on other sites

...in my mind i was referring to hot swapping the exact same DLL during runtime...

Ah, I get it.

 

It's been a while, so I don't know for certain, but it seems like the running program shouldn't be holding the dll file open after it loads it.  If not, you should be able to overwrite the file after it's loaded.  Then you could have the engine periodically check its modified date, and initiate swap proceedings when it sees that date change.

 

With a little attention to data handling and architecture you should be able to update lots of different systems on the fly without restarting the engine.  You could also choose to load dlls only in a development build, and link to static libraries for a release build.

Edited by VReality
0

Share this post


Link to post
Share on other sites

Since it is true that memory of a program thread is integrated, it is not just a "good manner" to free memory allocated in one dll in the same dll. A lot of guru's here, not long ago, said that deleting pointers allocated in  a different dll can result in memory leaks (in case of pool usage-a great advance of an mem isolated libs!), plus, it is a definite mark of a useless library, (what you did not create, why would you low level mage it :( ).

 

If you want to write isolated renderer, I have to stress that the main point of instructions isolation is the memory management safety. Your isolated framework will manage its memory while not allowing usage of the framework for leaking, at least the leaking that will not crush at the very moment (the devils bugs). On your way of writing an isolated library, I encourage you to do  following:

1- memory of your library that is exposed to outer dlls, should be passed out by a (read only) pointer!

2- memory of your library that is given from outer dll to create to should be accepted only as a reference to a pointer!

3- memory of your library that is given from outer dll to write to should be avoided, if cannot , pass it by a pointer! (realize that a 99% of such missusage you can replace by point 2-create-write)

4- memory of outer library passed to your library to read from, should be passed as a constant pointer!

 

Such as:

CLog* log=null;

CDevice* givemedevice=x->CreateDevice(&log);

 

or:

 

CDevice* device=null;

StaticUtilities::CreateDevice(&device);

StaticUtilities::DeleteDevice(device); // calls device->Release() if you forgot it, and then deletes the class itself

 

Remember that main point of isolation is memory management, and memory abusement imediate indicating. Correct isolation allows you to use memory pools, that means, especialy for renderer engines, which operate on large byte arrays tranfered from CPU to GPU, as a massive boost. Actualy your lib will be able to allocate 200MB  pool and nearly never use new/delete :), which are quite heavy CPU operations, OS realy does a whole pile of job at them. Of course, the pooling is the last step in lib creation, after you achieve final correct memory isolated ++ library.

 

 

 

0

Share this post


Link to post
Share on other sites

No.  Your dll will generally be compiled against the same memory manager as the rest of the engine (unless you do something to prevent it), and your engine is linked against the interface you expose from the dll, so generally, the engine can delete objects it gets from the dll.

How does one link against an interface? These preventative methods of which you speak, by that would you mean use an interface

 

In my implementation, the engine only handled a single dll specific object - the renderer itself.  All other render related objects handled by the engine were defined outside of the dll.  They were written in terms of the renderer's interface.  All data resources with API specific formats were held within the renderer internally, and referenced externally by ID (so the resource could swap out when the renderer did, without breaking external references).

So basically you've written a C-interface to your DLL, and have wrapped that within a class? Why not just go the whole hog and expose a C-interface instead?

 

That being said, code defined in the dll, including destructors and anything they call, can only be called while the dll is loaded.  So it's a bad idea for the renderer to be handing out objects implemented in the dll.
And yet you hand out a pointer to your renderer? You're just as likely to have a dangling pointer issue with the renderer as with any other class from that DLL, so what makes one class magically safe, and the others unsafe? 

 

A lot of guru's here, not long ago, said that deleting pointers allocated in  a different dll can result in memory leaks (in case of pool usage-a great advance of an mem isolated libs!), plus, it is a definite mark of a useless library, (what you did not create, why would you low level mage it sad.png ).

On linux it's perfectly safe to delete memory from other DSO's. On windows, deleting objects created in other DLL's is perfectly safe, so long as the class you're deleting has a virtual destructor. It's pretty easy to catch these errors though, just set your DLL to release, and link it to your debug exe. The debug CRT should throw an exception if you do anything nasty. Tools like VLD/valgrind may also be of use here.... 

 

If you want to write isolated renderer, I have to stress that the main point of instructions isolation is the memory management safety.

I don't agree with that statement. The most important thing is making sure you DLL interface is identical in both the DLL and EXE (so no external code in the interface, e.g. STL/boost) Isolating memory allocations is one of the simpler problems to deal with..... 

1- memory of your library that is exposed to outer dlls, should be passed out by a (read only) pointer!

In my experience, most people prefer using a mutable pointer to their renderer. A read-only renderer is about as useful as a car with no wheels. 

0

Share this post


Link to post
Share on other sites

 

 

On linux it's perfectly safe to delete memory from other DSO's

As I said, it can fall or not. You can delete a memory set by other module only if assumption that it was created with new operator is true. It usualy isn't,(in pro libs) and it is commonly just a pointer to a pool of the lib  , and many other stuff that would couse deleting it illegal (registered library resource and so on). Constructing library that way makes library unable to register, share, pool or anything else all its data, leaving on the user of the library a lot of unsafe dirty work.

 

Isolating memory allocations is one of the simpler problems to deal with.....

Isolating memory does not mean you delete somewhere else. It means that the module memory, if recreated or freed, does not couse outer program to approach the freed altered memory ever. That is source of spectacular problems. With correct isolation, your outer program will not do that, if all outer structers refer to pointer address of module mem, and not a pointer value. See why direct x is outputing Some** pointers, not Some* pointers to you? If used in correct way, any dx resource that gets freed in dx modules will thus let all outer structers "let know" that memory is not valid anymore. Robust memory isolation can make a C++ library nearly as safe to use as if you were coding in C# or other mem safe language when using it. This is not a marginal quality of a library, but rather the core point of isolation... if you do not achieve it, your isolation attempt will just complicate things up without any benefit.

 

prefer using a mutable pointer to their renderer.

Do I understand it the way that pointer is provided by renderer (the module) and mutable means they free it or recreate it on their own, as for memory point of view? Well in case of recreating some renderer object, you should call free and create routine of the renderer on the object  and get a new constant pointer, where is problem with that?

 

 

-1

Share this post


Link to post
Share on other sites
No.  Your dll will generally be compiled against the same memory manager as the rest of the engine (unless you do something to prevent it), and your engine is linked against the interface you expose from the dll, so generally, the engine can delete objects it gets from the dll.

How does one link against an interface? These preventative methods of which you speak, by that would you mean use an interface?

In visual studio, you would list the dll's corresponding .lib file as a dependancy of the .exe (more on import libraries here). 

 

Doing "something to prevent" the dll from using the same memory manager is not referring to a "preventative measure".  It's referring to situations like implementing your own memory management (e.g., overriding ::new) in your executable and forgetting to make your dll use your override as well.  If you're not doing anything like that, the dynamic linker will link the dll's "new" calls to the same "new" that's called by the .exe.

 

I suspect that most memory management worries with regard to libraries stem from the practice of publishing them to be used by others in unpredictable situations.  In that case, one must be very careful to ferret out all assumptions about how memory (and other system resources) might be handled on the other side of the .exe-.dll boundary.  Breaking systems of your project out into libraries, as we're discussing here, is not quite the same situation.

 

You're just as likely to have a dangling pointer issue with the renderer as with any other class from that DLL, so what makes one class magically safe, and the others unsafe?

Quantity and ownership.

 

If the .exe owns a single .dll exposed object, which owns all other .dll specific resources, it becomes trivial for the .exe to do its part to ensure that they go with the dll when it's unloaded.

 

If, on the other hand, the dll hands out pointers to dll specific resources, it becomes significantly less trivial to - er - "recall" them all when something decides it's time to swap out the dll.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • By NajeNDa
      Hi there,
      I am a game programmer (C#/C++) who is looking for a project to join. I am computer science engineer plus Master Degree in Game Development, currently working in one the most renown mobile games company (2 years academic experience, 1 year working experience).
      I have developed several prototypes or even games almost ready to release, but I always lack of artists, so I am looking for a project already set up or few artist to begin working in something.
      My preferences are:
      Unity or Unreal Engine 4 based project (UE4 prefered) PC/Console game prefered but mobile is acceptable Not interested in VR Serious team with almost all the roles filled or pretending to be filled 3D project prefered over Sprites Guaranteed 7 work hours per week, Crunch 20 work hours per week  European team (if timezone is not a problem for you, so it is not for me) I am not looking for any kind of money income from games neither the team, I want to do this as a hobby and a way to improve my skills.
      Cheers
    • By OPNeonGames
      SumiKen : Ink Blade Samurai is released! Download and leave a review to help support the game!
      Download here for free : https://play.google.com/store/apps/details?id=com.OPNeon.SumiKen&hl=en

      ★★★★★ - "Just get it it's the best runner!" - Icatsasha
      ★★★★★ - "Great game, wonderful art! Super addictive!" - EZk1ll 
      A casual samurai runner game with seven samurai and beautiful mountain paintings. Join Sumi and his samurai companions on this epic path to slash & dash through endless hordes of enemy lines. Beware of the enemy blades as a single blow from the sword blade will end it all. Will you be turned into faded ink? Or will you train and become a samurai legend?
       
    • By OPNeonGames
      Hey guys, posting my work in progress for Macho Cat here. 

      A very early prototype for Macho Cat. Everything is just placeholder for now
      What is Macho Cat?
      A silly little game where you scrub the macho cat with random objects found in trash and junkyard to please him
      Gameplay feature?
      -Cat scrubbin, lots of scrubbin
      -Unlock moar objects in junkyard 
      -Funny, silly and easy
      When will the game release?
      December 2017 (estimate)
      Interested to Beta test?
      opneongame@gmail.com
    • By MCKillerZ1
      UNITY ENGINE
      IN SEARCH FOR MEMBERS
       
      Hey there. I am currently looking for at least 4 members ( for now ) to join me in making games together.
      Sure, I'm still a student ( 17 years old ) but this is what I wish to achieve in the future.
       
      My goal is simple:
      :- Create my own game development team consisting of 5 members total.
      :- Work together as a team, and also learn game related things together.
      :- Successfully finish a simple game, and upload it to any source ( Google Play, Steam, Origin, etc... )
      :- Gain popularity as a team over the time.
       
      My role in the team is the producer or manager, or maybe the leader.
      I do have talent regarding to creating games. My main ability is creating 3D Models via SketchUp, and I've had experience doing it for about 2-3 years.
      I did learn a bit of programming, but I only understand the basics of it. I can't really make a functioning program.
      Currently, I'm learning the basics of making music using FL Studio 12, and I will learn basic animation, level design and character modelling in the future.
       
      Requirements To Join:
      1. Good English communicating skills.
      2. Always online whenever needed.
      3. Good internet connection/speed.
      4. Have a decent computer/laptop.
      5. At least knows the basics of game development related topics.
      6. Have a good camera and a set of headphones with mic, or just regular mic ( needed in the future ).
       
      Roles Available:
      1. Programmer - Main language is C#, but can also use Java ( I recommend C# ).
      2. Music Producer - Can create music according to the game's settings, and also create sounds.
      3. Animator - Can do decent animation of characters, vehicles and more.
      4. Graphics Designer - Able to do colour schemes, 2D sprites and more.
       
      Send me a message if interested.
       
       
    • By OPNeonGames
      Hey guys, posting my work in progress for Macho Cat here. 

      A very early prototype for Macho Cat. Everything is just placeholder for now
      What is Macho Cat?
      A silly little game where you scrub the macho cat with random objects found in trash and junkyard to please him
      Gameplay feature?
      -Cat scrubbin, lots of scrubbin
      -Unlock moar objects in junkyard 
      -Funny, silly and easy
      When will the game release?
      December 2017 (estimate)
      Interested to Beta test?
      opneongame@gmail.com
  • Popular Now