Get struct from .dll using QLibrary
-
wrote on 8 Jan 2013, 12:10 last edited by
I have .dll file and functions in it(exported functions using extern c).Function from .dll returns struct.I dont have .h file for dll.
How can I get struct as return using QLibrary.I need to use functions pointers.
-
wrote on 8 Jan 2013, 13:28 last edited by
Does it really return a struct by value ???
Would be much more common it returns a pointer to the struct, while the struct is located in memory owned by the DLL. Either that, or it copies the struct into a memory buffer provided by the caller (via pointer). Unless you have the exact definition of both, the function and the struct it returns (usually that is taken from the corresponding header file), this is going to fail! Guessing doesn't help! How comes you don't have a header file?
Anyway, you would go something like that:
@//Define the struct
typedef struct
{
/put struct fields hier, exactly as defined in original library !!!/
}
my_struct_t;//Define suitable function pointer
typedef my_struct_t (*my_function_t)( /declare arguments here, if any!/ );QLibrary myLib("whatever.dll")
if(myLib->load())
{
my_function_t ptr = NULL;
ptr = (my_function_t) myLib->resolve("some_fancy_function_name");
if(ptr)
{
my_struct_t value = ptr( /pass arguments here, if any/ );
doSomethingWith(value);
}
}@Note that "some_fancy_function_name" must be the name of the DLL export (entry point).
Check with Dependency Walker, if you are not sure...
-
wrote on 24 Jan 2013, 12:16 last edited by
thanks lot..
-
wrote on 5 Feb 2013, 13:04 last edited by
I have other issue in using QLibrary.
This time I have CSampleclass.h and sample.dll.
CSampleclass object returned from sample.dll reslove in void*.
But Once I have CSampleclass object can I access CSampleclass functions by including header file? -
wrote on 5 Feb 2013, 13:10 last edited by
Nope! You can't use C++ objects via QLibrary that way, I think !!!
Instead you would have to create "C style" wrapper functions on the DLL side like those:
@/* --- Public DLL API ---*/
#include "MyClass.h"
#define DLL_API __declspec(dllexport)
extern "C"
{
DLL_API void* myclass_create(void)
{
return new MyClass();
}DLL_API int myclass_do_something(void *obj) { MyClass *inst = reinterpret_cast<MyClass*>(obj); return (inst) ? inst->doSomething() : (-1); } /* ... */ DLL_API void myclass_destroy(void **obj) { MyClass *inst = reinterpret_cast<MyClass*>(*obj); *obj = NULL; if(inst) delete inst; }
}@
Then each of those "wrapper" functions can be called via QLibrary.
@/* --- Main Program --- */
typedef void* (myclass_create_t)(void);
typedef int (myclass_do_something_t)(void);
typedef void (myclass_destroy_t)(void);myclass_create_t myclass_create_ptr = NULL;
myclass_do_something_t myclass_do_something_ptr = NULL;
myclass_destroy_t myclass_destroy_ptr = NULL;QLibrary lib("whatever.dll")
if(lib->load())
{
myclass_create_ptr = (myclass_create_t) lib->resolve("myclass_create");
myclass_do_something_ptr = (myclass_do_something_t) lib->resolve("myclass_do_something");
myclass_destroy_ptr = (myclass_destroy_t) lib->resolve("myclass_destroy");
}if(myclass_create_ptr && myclass_do_something_ptr && myclass_destroy_ptr)
{
void *object = myclass_create_ptr(); //equals: object = new MyClass()
int ret = myclass_do_something_ptr(object); //equals: ret = object->doSomething()
myclass_destroy_ptr(&object); //equals: delete object
}@(This all is required because just passing the pointer to the object isn't sufficient. Even if the "main" program knows what member methods the object/class has, from the header file, it cannot know what the address [entry point] of those functions is - if the DLL was loaded via QLibrary. You would get linker errors otherwise...)
-
wrote on 6 Feb 2013, 01:15 last edited by
Updated the above example code quite a bit...