Calling a DLL function

Started by
8 comments, last by M_maker 2 months, 1 week ago

Hello.

I have a problem with getting function ptr at runtime, an example of a class is below.

I use CScriptHandle and funcdefs in a script to call a function that will be registered after the script will be compiled.

bool library::load(const std::string & libname) {

lib = LoadLibraryA(libname.c_str());

if (lib != NULL)

return true;

return false;

}

CScriptHandle library::get_function(std::string function_address, std::string function_signature){

FARPROC procAddress = GetProcAddress(lib, function_address.c_str());

if (procAddress) {

typedef void* (*FunctionType)(...);

FunctionType function = reinterpret_cast<FunctionType>(procAddress);

asIScriptContext* ctx = asGetActiveContext();

asIScriptEngine* engine = ctx->GetEngine();

asUINT func_id= engine->RegisterGlobalFunction(function_signature.c_str(), asFUNCTION(function), asCALL_CDECL);

asIScriptFunction* f = engine->GetFunctionById(func_id);

CScriptHandle h;

h.Set(f, f->GetObjectType());

return h;

}

}

void library::unload() {

FreeLibrary(lib);

}

function signature is

engine->RegisterObjectMethod("library", "ref@ get_function(const string&in, const string &in)", asMETHOD(library, get_function), asCALL_THISCALL);

my script is

funcdef int message_box(int, string, string, int);

library l;

void main(){

l.load("C:/windows/system32/user32.dll");

message_box@msg=cast<message_box>(l.get_function("MessageBoxA", "int msgbox(int, string, string, int)"));

msg(0, "Test text", "Test title", 0);

}

But instead of message_box, I get the an error

NGTRuntimeError

info: func: void main()

modl: ngtgame

sect: G:/projects/NGT/NGTScript/library_test.ngt

line: 7

desc: Unbound function called

--- call stack ---

But I return handle to the function, as shown in library class. What's my mistake? Thanks for your help.

Advertisement

I don't see anything immediately wrong with your code.

Have you tried debugging the CScriptHandle to see if everything is behaving as expected?

Set a breakpoint in CScriptHandle::Set and ensure the asIScriptFunction is indeed stored.

Set another breakpoint in CScriptHandle::Cast and ensure the script is giving the appropriate type id and that the script handle is able to return the stored asIScriptFunction.

If I get the time I will try to test this out myself to see if I can identify what needs to change to make it work.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

@WitchLord I can't get it from locals. this Unable to evaluate the expression. Variable is optimized away and not available. 1 of 8 level 1

Compile your application without optimizations, it won't affect the end result but you will be able to debug and see the values.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I found NameValueType

h

0x000002645f45976c {m_ref=0x0000000000000000 m_type=0x0000000000000000 <NULL> }

CScriptHandle *

m_ref

0x0000000000000000

void *

◢ m_type

0x0000000000000000 <NULL>

asITypeInfo *

__vfptr

<Unable to read memory>

void * *

This shows that the CScriptHandle is still not holding any value (both m_ref and m_type are null).

At which point did you see these values? When entering Set() or when entering Cast()?

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

@WitchLord With set, however, if, for example, I specify a non-existent function in get_function, the program just crashes. And if, for example, I successfully receive a ProcAddress of a function, the application will not crash, but will return a runtime error angelscript that there is no such function.

I finally got the time to investigate this is in more detail.

The problem is that you used asIScriptFunction::GetObjectType rather than asIScriptFunction::GetTypeId to determine the type of the function. GetObjectType is used to determine the type of object for class methods.

Change your code to the following and it should work:

h.Set(f, engine->GetTypeInfoById(f->GetTypeId()));

Of course, you should know that MessageBoxA is not compatible with the function signature you're informing so you're likely going to get a crash once you're able to call the function.

Rather than std::string, it takes char* as parameters. And if I'm not mistaken it uses the asCALL_STDCALL calling convention.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Thank you very much! Now everything works.

This topic is closed to new replies.

Advertisement