Sign in to follow this  
SteveDeFacto

How to pass function handle from GetProcAddress to luabind::def?

Recommended Posts

In my games scripting I need to offer the ability to add extra functions from DLLs. I'm using lua and luabind for scripting in my game but I can't seem to pass the FARPROC to luabind::def how do I bind the function GetProcAddress to lua?
void def_function(std::string lib_name, std::string script_name)
{
	FARPROC func = GetProcAddress( handle, lib_name.c_str() );
	luabind::module( g_Lua )
	[
		luabind::def( script_name.c_str(), func )
	];
}

Share this post


Link to post
Share on other sites
A FARPROC isn't really anything meaningful, it needs cast to the correct function pointer type to call it. So you could pass it to luabind as any pointer/light userdata type (Assuming luabind allows that).

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
A FARPROC isn't really anything meaningful, it needs cast to the correct function pointer type to call it. So you could pass it to luabind as any pointer/light userdata type (Assuming luabind allows that).


I'm not entirely sure I understand what you are saying but I have tried int, DWORD and void* but none of them worked.

I normally just put the name of the function in that spot, I know luabind is using boost, maybe I need to use some type of boost function pointer?

Share this post


Link to post
Share on other sites
Luabind uses compile-time introspection to figure out the signature of the method to call. You can store the function pointer in a small wrapper class and then pass a function on that wrapper class to luabind instead.

Share this post


Link to post
Share on other sites
Quote:
Original post by Codeka
Luabind uses compile-time introspection to figure out the signature of the method to call. You can store the function pointer in a small wrapper class and then pass a function on that wrapper class to luabind instead.


I honestly don't know how to do that, can you show me what you mean?

Share this post


Link to post
Share on other sites
Have you tried casting the return value of GetProcAddress to a function pointer with a signature that matches the function you are binding? For example, consider a void function taking an int as its only parameter:


void (*test)(int) = (void (*)(int)) GetProcAddress(handle, "test");
//...
luabind::def( "test", function );



By itself, the FARPROC is merely the address at which the function starts. Because luabind needs type information in order to generate the appropriate glue code, providing the address is not sufficient. By casting it to a function pointer with the appropriate signature, you should be able to supply luabind with the information it needs. Note that I haven't tested this code.

Share this post


Link to post
Share on other sites
Quote:
Original post by Windryder
Have you tried casting the return value of GetProcAddress to a function pointer with a signature that matches the function you are binding? For example, consider a void function taking an int as its only parameter:

*** Source Snippet Removed ***

By itself, the FARPROC is merely the address at which the function starts. Because luabind needs type information in order to generate the appropriate glue code, providing the address is not sufficient. By casting it to a function pointer with the appropriate signature, you should be able to supply luabind with the information it needs. Note that I haven't tested this code.


I hate to bump such an old post but I've been on vacation and have not been able to reply, anyway so what you are saying is that I need to define the structure of the function in order to pass it to luabind?

The problem with this is that it completely voids the point of adding libraries to my scripting since I would have to recompile the engine in order to add new functions or classes...

Also the code you posted is very vague, I don't understand what the test class is or how the class can represent the structure of the function?

Is there another way to pass the structure of the function during runtime to luabind?

Share this post


Link to post
Share on other sites
Quote:
I hate to bump such an old post
Three days isn't that old :)
Quote:
The problem with this is that it completely voids the point of adding libraries to my scripting since I would have to recompile the engine in order to add new functions or classes...
My understanding is that Luabind requires the signature of the functions that you register to be known at compile time. This is how Luabind was designed to work, and makes sense given the mechanisms that it uses.

It seems that what you're wanting is to register functions with Lua via Luabind whose signatures are not known at compile time. A question you might ask is, if Luabind doesn't know what arguments the function accepts, how is it supposed to call the function? And if all it has is a generic pointer to the function, how would it even cast the pointer to the appropriate type in order to call it?

Here's one way you might think about the problem. Say you were just using 'plain' Lua (without a binding library), and wanted to register arbitrary functions at run time. How would you do it? When it came time to gather the arguments and invoke the function on the C++ side, what would the syntax look like?

I use Lua and Luabind, but I'm not an expert on either, so maybe there's a solution to this problem that I haven't thought of - if so, I'm sure someone will come along and post it :)
Quote:
Also the code you posted is very vague, I don't understand what the test class is or how the class can represent the structure of the function?
The code Windryder posted isn't vague, but it might have a typo in it. I think maybe the first line was supposed to be:
void (*function)(int) = (void (*)(int)) GetProcAddress(handle, "test");

Share this post


Link to post
Share on other sites
Quote:
Original post by SteveDeFacto
The problem with this is that it completely voids the point of adding libraries to my scripting since I would have to recompile the engine in order to add new functions or classes...
As jyk says, you need to at least know the parameters and return type of the function in order to actually call it. That doesn't mean you can't load functions at runtime, though, just that you need to settle on a "standard" signature that all "plugin" functions need to provide.

Share this post


Link to post
Share on other sites
Quote:
Original post by Codeka
Quote:
Original post by SteveDeFacto
The problem with this is that it completely voids the point of adding libraries to my scripting since I would have to recompile the engine in order to add new functions or classes...
As jyk says, you need to at least know the parameters and return type of the function in order to actually call it. That doesn't mean you can't load functions at runtime, though, just that you need to settle on a "standard" signature that all "plugin" functions need to provide.


There is no way I can provide a "standard" signature for all functions since all functions will have different inputs and outputs, the better option would be to use pure lua to bind the functions and classes but there are quite a few problems with that as well.

Programming plugins would be a huge pain since all functions would be lua functions and the DLL would have to include lua.hpp further more when I add classes this problem would only be worse...

There must be some way to provide a new signature at runtime?

Share this post


Link to post
Share on other sites
Quote:
Original post by SteveDeFacto
There is no way I can provide a "standard" signature for all functions since all functions will have different inputs and outputs, the better option would be to use pure lua to bind the functions and classes but there are quite a few problems with that as well.

In C, you would have something like:

void (*arbitrary_C_plugin_function)(void*)

Where the void* parameter points to a context-dependent structure, or variable, or whatever else the particular function needs. That shifts the burden to the caller of the function, who needs to make sure they're passing in the right parameter. The code inside the function itself then knows how to properly cast the pointer to get the data it needs.

In C++, it looks more like:

void (*arbitrary_CPP_plugin_function)(const BaseData*)
or (if you have an instance)
void (SomeType::*arbitrary_CPP_plugin_function)(const BaseData*)

Where BaseData is a polymorphic type that can be downcast to the appropriate derived type based on the function. The only real difference is that you have a little more control over what the user passes in since it needs to be derived from BaseData, and you can leverage RTTI to make sure it's the correct type.

These solutions aren't ideal since things can still easily blow up at run-time if the calling code passes in the wrong thing, but that's how you handle the general case when you don't know the data types (or how much there will be) at compile-time. It isn't a bad idea to create wrapper functions around the plug-in functions that take the proper, compile-tile-checked parameters, so that you reduce the possible points of failure to a single location. However I'm not sure how much of this is possible in Lua.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zipster
Quote:
Original post by SteveDeFacto
There is no way I can provide a "standard" signature for all functions since all functions will have different inputs and outputs, the better option would be to use pure lua to bind the functions and classes but there are quite a few problems with that as well.

In C, you would have something like:

void (*arbitrary_C_plugin_function)(void*)

Where the void* parameter points to a context-dependent structure, or variable, or whatever else the particular function needs. That shifts the burden to the caller of the function, who needs to make sure they're passing in the right parameter. The code inside the function itself then knows how to properly cast the pointer to get the data it needs.

In C++, it looks more like:

void (*arbitrary_CPP_plugin_function)(const BaseData*)
or (if you have an instance)
void (SomeType::*arbitrary_CPP_plugin_function)(const BaseData*)

Where BaseData is a polymorphic type that can be downcast to the appropriate derived type based on the function. The only real difference is that you have a little more control over what the user passes in since it needs to be derived from BaseData, and you can leverage RTTI to make sure it's the correct type.

These solutions aren't ideal since things can still easily blow up at run-time if the calling code passes in the wrong thing, but that's how you handle the general case when you don't know the data types (or how much there will be) at compile-time. It isn't a bad idea to create wrapper functions around the plug-in functions that take the proper, compile-tile-checked parameters, so that you reduce the possible points of failure to a single location. However I'm not sure how much of this is possible in Lua.


I cannot do that because I am trying to make the scripting simple and easy to use, the user would have to pack the variables before using them with a plugin function, this would make scripting with plugins a very painful task and I was hoping to at some point transfer all primary engine functions to plugins.

I don't mind storing extra data for the function signature in the plugin but I don't know how to use that data at runtime. If luabind has the ability to bind standard c++ functions to lua then I know there is a way to do this I just don't know how.

Share this post


Link to post
Share on other sites
Quote:
If luabind has the ability to bind standard c++ functions to lua then I know there is a way to do this I just don't know how.
The 'if-then' statement above doesn't really follow, IMO.

Basically what you're saying is, 'If Luabind can bind C++ functions for which the type is known at compile time, then it must be able to bind C++ functions for which the type is not known at compile time'. That's kind of like saying, 'If people can walk, then they must be able to fly', which obviously isn't true in the general case. In other words, we're talking about two very different things here, and just because one is possible doesn't mean that the other must also be possible.

As I suggested before, I think a good first step would be to set aside trying to determine how it can be done using Luabind, and instead think a bit about how it could be done at all. To put it another way, if it's possible to do with Luabind, it should be possible to do without Luabind also (Luabind is just C++ code, after all), so how would you do it? On the C++ side, how exactly would you go about calling the function? What would the syntax look like?

I'm not saying it can't be done, and maybe there's a clever (or even not-so-clever) solution to your problem that I haven't thought of. The sense I'm getting though is that you're wanting to do something that's fundamentally at odds with the C++ language, and that you therefore might have to reconsider some aspects of your design. (Perhaps I'll be proven wrong about that though.)

Share this post


Link to post
Share on other sites
Assuming you have control over the DLL, just write the DLL function to use the Lua-standard C-function signature (int func(lua_State* L)), then use lua_register to register it under whatever name you like. On the C side, you'll need to pull args off the stack using normal (non-LuaBind) means.

Alternatively, just have the DLL export a function that, when called with a lua_State*, registers all its functions into that state's global namespace. (Basically this function would just call module.) Then you can use LuaBind on both sides.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Quote:
If luabind has the ability to bind standard c++ functions to lua then I know there is a way to do this I just don't know how.
The 'if-then' statement above doesn't really follow, IMO.

Basically what you're saying is, 'If Luabind can bind C++ functions for which the type is known at compile time, then it must be able to bind C++ functions for which the type is not known at compile time'. That's kind of like saying, 'If people can walk, then they must be able to fly', which obviously isn't true in the general case. In other words, we're talking about two very different things here, and just because one is possible doesn't mean that the other must also be possible.

As I suggested before, I think a good first step would be to set aside trying to determine how it can be done using Luabind, and instead think a bit about how it could be done at all. To put it another way, if it's possible to do with Luabind, it should be possible to do without Luabind also (Luabind is just C++ code, after all), so how would you do it? On the C++ side, how exactly would you go about calling the function? What would the syntax look like?

I'm not saying it can't be done, and maybe there's a clever (or even not-so-clever) solution to your problem that I haven't thought of. The sense I'm getting though is that you're wanting to do something that's fundamentally at odds with the C++ language, and that you therefore might have to reconsider some aspects of your design. (Perhaps I'll be proven wrong about that though.)


I was thinking that if luabind can turn the name, signature and function pointer into a function that can be called from lua then I could do the same but maybe it's doing things differently then I'm thinking.

Quote:
Original post by Sneftel
Assuming you have control over the DLL, just write the DLL function to use the Lua-standard C-function signature (int func(lua_State* L)), then use lua_register to register it under whatever name you like. On the C side, you'll need to pull args off the stack using normal (non-LuaBind) means.

Alternatively, just have the DLL export a function that, when called with a lua_State*, registers all its functions into that state's global namespace. (Basically this function would just call module.) Then you can use LuaBind on both sides.


Yes I agree this is the best option that I can think of but I still believe it is possible to use functions from a DLL without including lua or luabind into the DLL.

I know that when you export the functions from the DLL as C++ functions the signature is mangled in with the name, I can probably demangle it and get the signature but once I have this data how would I represent it as a function that can be passed to luabind?

Share this post


Link to post
Share on other sites
Quote:
I was thinking that if luabind can turn the name, signature and function pointer into a function that can be called from lua then I could do the same but maybe it's doing things differently then I'm thinking.
As you stated, Luabind can turn a name, a function pointer, and a signature into a function that can be called from Lua. The signature, however, must be known at compile time. What you're wanting to do is somehow to register a function whose signature is not known until run time, which is a different problem.
Quote:
Yes I agree this is the best option that I can think of but I still believe it is possible to use functions from a DLL without including lua or luabind into the DLL.
Assuming there are no technical problems in general with registering functions from a DLL via Luabind (I've never tried it myself, so I can't say for sure), then it should absolutely be possible to use functions from a DLL without including Lua or Luabind in the DLL. However, I believe that the signatures of those functions will still need to be known at compile time.
Quote:
I know that when you export the functions from the DLL as C++ functions the signature is mangled in with the name, I can probably demangle it and get the signature but once I have this data how would I represent it as a function that can be passed to luabind?
I don't know that that info would do you much good, since one way or another, the function eventually has to be called from your C++ code, and in order to do that you need to know its signature at compile time, not run time.

If I'm wrong about any of this I'm sure someone will correct me, but at the moment at least I can't think of a way to do what you're wanting to do.

Share this post


Link to post
Share on other sites
I figured it out, first you define the functions as C++ functions in the DLL, demangle the function pointer to get the signature of the function, create a lua function inside your program as a wrapper, in that function call the DLL function using assembly and bind the lua wrapper function under the name of the function that is to be called from the DLL.

One thing I still don't know is how to get the name of the function that is suppose to be gotten from the DLL out of the lua stack but I'm sure it won't be to hard to figure out.

Here is a tutorial on executing DLL functions with a runtime defined signature.

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