Jump to content

C++ dll manipulating objects created in lua


Recommended Posts

So with all this cool stuff of videos and website on cubes I thought, this stuff needs to get into lua. Yet these are using C++ libraries. So how can this work? Well, I figured out, with the help of Josh & the guy who created the lua implementation, although I was really close and just needed a nudge in the right direction...anyway


The Goal


Create a cube in lua

Create a dll in C++ that will rotate the lua cube inside the editor

The idea is that if I can do this, I can pass any object created in lua from the editor to your own dll and run LE functions on it. This can help make things like having videos and webpages on models as easy as setting a property for that object in the editor. Or AI stuff being done in C++ code instead of lua to help speed things up.


This is still pretty rough around the edges. Not every detail has been worked out, but just getting it to work was pretty cool :lol:



What you need:


Lua Library

Leadwerks (obviously)

C++ Compiler (VS is preferred by me)

Patience :D



1. Create a C++ dll.

a. File->New Project

b. Visual C++->Win32->Win32 Console Application

c. Next in the wizard->DLL->Empty Project

d. Add your main.cpp file & LE's engine.cpp

e. Project->Properties->Configuration Properties->C/C++->General, add include directories to LE's CPP and Lua's Include folder

f. Project->Properties->Configuration Properties->Linker->Input, add the 2 lua .lib files here. Be sure to put in "'s


Copy the below code for your main code:


#define LUA_API_EXP __declspec(dllexport)

#include "engine.h"
#include <string>

using namespace std;

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

// prevents the function name from being mangled
LUA_API_EXP int luaopen_test(lua_State *L);

static int RickRotate(lua_State* L)
// returns a pointer to the pointer char**
TEntity entity = *(TEntity*)lua_touserdata(L, 1);

TurnEntity(entity, Vec3(0, 1, 0));

return 0;

static int Init(lua_State* L)

return 0;

static const luaL_reg testlib[] =
{"Init", Init},
{"RickRotate", RickRotate},

LUA_API_EXP int luaopen_test(lua_State *L)
luaL_openlib(L, "Rick", testlib, 0);
return 1;


Compile the DLL in release mode. Copy this DLL, the engine.dll, lua5.1.dll, lua51.dll and maybe newton.dll and JointLibrary.dll to one of the lua models that you want to run this test on.


Inside whatever lua model you want to run, open the lua file for it. In the CreateObject() method copy this line in, replacing the directory path of your dll to where ever you placed it:


assert(package.loadlib("C:\\Program Files\\Leadwerks Engine SDK\\Models\\Entities\\Pi\\Pi-Cube\\Rick.dll", "luaopen_test"))()


This will load your dll so it can be used in lua and call the luaopen_test method right away. This creates the Rick object for lua. Then it calls the Init() function of the Rick object, which inits the LE DLL for use.


Then in your lua models Update() method call:




This assume you assigned the model passed to CreateObject, to a variable object.model.


If everything worked out correctly you should see your model rotating in the editor.

If not, feel free to post the error and I'll try to help.


I'm hoping that this starts opening up many doors for lua.

Link to comment
Share on other sites

It sounds like what is happening is the DLL performs all the math on the entity object, but it has a separate instance of the engine running. If you tried to do some other operations that allocated memory it would probably crash.


It actually is possible to do something like this, but you would need to pass all the engine function pointers to the DLL so it could call the functions the main engine is using.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Ah, so not a very good way to do things eh? I've actually started reading up a little on C++ + LUA. It seems LUABind does fairly well at creating an interface between the two languages and passing function pointers between the two. Leadwerks currently does the same thing doesn't it?

Programmer, Modeller

Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64

Visual Studio 2008 | Photoshop CS3 | Maya 2009

Website: http://srichnet.info

Link to comment
Share on other sites

Sigh, yeah seems like it is so. Trying to create a material and assign it to a model passed to it from Lua causes a crash. Any chance of getting some sort of hook in the editor that calls a given DLL, like mod.dll and passing it the framework in use or something that would allow the dll to share the LE engine instance that the editor is using? Then we could replace/extend mod.dll with our own custom code?


This still works out well for pure math functions like pathfinding or heavy calculations, but you have to pass the data back to Lua for it to make the actual engine calls.

Windows 7 x64 - Q6700 @ 2.66GHz - 4GB RAM - 8800 GTX

ZBrush - Blender

Link to comment
Share on other sites

If the dll can use a TEntity, does that mean that if the dll inits a new instance of the engine we could pass the world and buffers and then be able to allocate materials and paint them?


Niosop, when you tried to create a material and assign it, did you do the whole Graphics() and other initing LE commands first? Maybe put that stuff in the Init() method. I'd guess that would work. I have to work now but will give that stuff a try when I get home.

Link to comment
Share on other sites

Actually I'm trying another approach now. Allocating all the various things in Lua (materials, textures, etc) and just manipulating them in the DLL. So for the video player it will maintain the video data, but Lua will create the texture and pass that to the DLL which will try and copy the video data to the texture. Will let you know how that turns out.

Windows 7 x64 - Q6700 @ 2.66GHz - 4GB RAM - 8800 GTX

ZBrush - Blender

Link to comment
Share on other sites

I would assume that would work. I still want to figure this out. I'm 99% sure that the dll will be able to allocate objects IF we can call Graphics(). Of course that would create a separate window, but that can be hidden. It's not idea, but really the graphics system just needs to be created and no window. Once that's up passing in the world and maybe some buffers should allow every command to be done on anything you pass in. We already know by passing in the pointer to the object the dll has access to it, which is why commands that manipulate objects works. The reason you can't create a texture in the dll is because Graphics() wasn't called. If we can get Graphics() called in the dll, then you will be able to make a texture object and apply it to an object. This is essentially like having 2 LE graphics systems running at the same time, and they have access to each others data because we are passing around pointers.


I think the really cool thing with this is that this combined with coroutines could basically treat it like a separate thread. You pass your lua object to the dll and then in a coroutine from lua you call a function in your dll that does all the playing of the data. Because it's a coroutine the rest of the lua program continues to work, while the coroutine stays in the dll running it's own loop.


Or lua also has threads that we might be able to take advantage of.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Create New...