Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Dynamicly calling functions from DLL / C++ / Builder

kharonkharon Member Posts: 2
i have a basic DLL ( generated with C++Builder ) and i want to load that file "dynamicly" without DEF file loading or creating with using LoadLibrary GetProcAddress Casting and FreeLibrary :

// MY DLL Implementation ----
[code]
#include
#include
#include "dllfile.h"

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}

EXPORT int __stdcall Function( int a, int b) {
std::cout << "Toplam = " << (a+b) << std::endl;
return 0 ;
}
[/code]
// dllfile.h ------
[code]
#define EXPORT extern "C" __declspec( dllexport )
EXPORT int __stdcall Function( int a, int b) ;
[/code]
I have compiled with no error and i have created a DLL successfully. But when i call my function with console C++ application
[code]
typedef int (__stdcall *ptrFunc) (int, int) ;
ptrFunc Func ;

int main(int argc, char* argv[])
{

HINSTANCE handle = LoadLibrary("mydll.dll") ;
Func = static_cast < ptrFunc > ( GetProcAddress(handle,"Function") );
Func(4,5) ;
return 0;

}
[/code]
the casting error occurs;
[b]E2031: Cannot cast from int (__stdcall *)() to "int (__stdcall *)(int, int)[/b]


Comments

  • LundinLundin Member Posts: 3,711
    : i have a basic DLL ( generated with C++Builder ) and i want to load that file "dynamicly" without DEF file loading or creating with using LoadLibrary GetProcAddress Casting and FreeLibrary :
    :
    : // MY DLL Implementation ----
    : [code]
    : #include
    : #include
    : #include "dllfile.h"
    :
    : #pragma argsused
    : int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    : {
    : return 1;
    : }
    :
    : EXPORT int __stdcall Function( int a, int b) {
    : std::cout << "Toplam = " << (a+b) << std::endl;
    : return 0 ;
    : }
    : [/code]
    : // dllfile.h ------
    : [code]
    : #define EXPORT extern "C" __declspec( dllexport )
    : EXPORT int __stdcall Function( int a, int b) ;
    : [/code]
    : I have compiled with no error and i have created a DLL successfully. But when i call my function with console C++ application
    : [code]
    : typedef int (__stdcall *ptrFunc) (int, int) ;
    : ptrFunc Func ;
    :
    : int main(int argc, char* argv[])
    : {
    :
    : HINSTANCE handle = LoadLibrary("mydll.dll") ;
    : Func = static_cast < ptrFunc > ( GetProcAddress(handle,"Function") );
    : Func(4,5) ;
    : return 0;
    :
    : }
    : [/code]
    : the casting error occurs;
    : [b]E2031: Cannot cast from int (__stdcall *)() to "int (__stdcall *)(int, int)[/b]
    :
    :
    :

    Casting between different kinds of function pointers is undefined behaviour, at least in C. But nevermind that, and nevermind static_cast either. Just do a normal typecast and it will work fine:

    Func = (ptrFunc) (GetProcAddress(handle,"Function") );
  • bilderbikkelbilderbikkel Member Posts: 754
    : : [code]
    : : typedef int (__stdcall *ptrFunc) (int, int) ;
    : : ptrFunc Func ;
    : :
    : : int main(int argc, char* argv[])
    : : {
    : :
    : : HINSTANCE handle = LoadLibrary("mydll.dll") ;
    : : Func = static_cast < ptrFunc > ( GetProcAddress(handle,"Function") );
    : : Func(4,5) ;
    : : return 0;
    : :
    : : }
    : : [/code]
    : : the casting error occurs;
    : : [b]E2031: Cannot cast from int (__stdcall *)() to "int (__stdcall *)(int, int)[/b]

    : Casting between different kinds of function pointers is undefined behaviour, at least in C. But nevermind that, and nevermind static_cast either. Just do a normal typecast and it will work fine:
    :
    : Func = (ptrFunc) (GetProcAddress(handle,"Function") );

    But Lundin, what causes the compiler to think there are two different kinds of function pointers? They ARE all of the same type? So where did the compiler get the [b]int (__stdcall *)()[/b] from?

    Just curious... Thanks in advance,
    bilderbikkel

  • LundinLundin Member Posts: 3,711
    : : : [code]
    : : : typedef int (__stdcall *ptrFunc) (int, int) ;
    : : : ptrFunc Func ;
    : : :
    : : : int main(int argc, char* argv[])
    : : : {
    : : :
    : : : HINSTANCE handle = LoadLibrary("mydll.dll") ;
    : : : Func = static_cast < ptrFunc > ( GetProcAddress(handle,"Function") );
    : : : Func(4,5) ;
    : : : return 0;
    : : :
    : : : }
    : : : [/code]
    : : : the casting error occurs;
    : : : [b]E2031: Cannot cast from int (__stdcall *)() to "int (__stdcall *)(int, int)[/b]
    :
    : : Casting between different kinds of function pointers is undefined behaviour, at least in C. But nevermind that, and nevermind static_cast either. Just do a normal typecast and it will work fine:
    : :
    : : Func = (ptrFunc) (GetProcAddress(handle,"Function") );
    :
    : But Lundin, what causes the compiler to think there are two different kinds of function pointers? They ARE all of the same type? So where did the compiler get the [b]int (__stdcall *)()[/b] from?
    :
    : Just curious... Thanks in advance,
    : bilderbikkel
    :
    :

    It is the FARPROC type returned from GetProcAddress.

    I can show a little trick I use when importing DLL functions.
    Here is from some code I once wrote:

    [code]
    union
    {
    struct
    {
    void (__stdcall* listener_EnableWarnings)(bool enabled);
    bool (__stdcall* listener_OpenCom)(const char* port, const char* baudrate);
    void (__stdcall* listener_CloseCom)(void);
    void (__stdcall* listener_ShowListener)(int);
    void (__stdcall* listener_KillListener)(void);
    }func;

    void (__stdcall* dsipFunc[N_FUNC])(void);
    }dsipFunctions;

    #define listener_EnableWarnings dsipFunctions.func.listener_EnableWarnings
    #define listener_OpenCom dsipFunctions.func.listener_OpenCom
    #define listener_CloseCom dsipFunctions.func.listener_CloseCom
    #define listener_ShowListener dsipFunctions.func.listener_ShowListener
    #define listener_KillListener dsipFunctions.func.listener_KillListener
    [/code]


    First I list all the different functions in the DLL one by one.
    Then in the same union I list them as an array of function pointers of the same type. After all, they are only 32-bit integers in the end so you know that you can typecast from one function pointer to the other without causing trouble, as long as you use right return type and parameters when you call the actual function.

    This has another advantage as well: I can open all DLL functions in a loop:

    [code]
    for(short i=0; i<N_FUNC; i++)
    {
    dsipFunctions.dsipFunc[i] = (void(__stdcall*)(void)) GetProcAddress(hDLL,funcNames[i]);
    if(dsipFunctions.dsipFunc[i]==NULL)
    {
    std::cerr << "Couldn't find " << funcNames[i] << " in " << DLL_PATH << "." << std::endl;
    return 1;
    }
    }

    [/code]
  • bilderbikkelbilderbikkel Member Posts: 754
    :-)

    See ya,
    bilderbikkel

  • NiffarellaNiffarella Member Posts: 1
    : This has another advantage as well: I can open all DLL functions in
    : a loop:
    :
    : [code]:
    : for(short i=0; i<N_FUNC; i++)
    : {
    : dsipFunctions.dsipFunc[i] = (void(__stdcall*)(void)) GetProcAddress(hDLL,funcNames[i]);
    : if(dsipFunctions.dsipFunc[i]==NULL)
    : {
    : std::cerr << "Couldn't find " << funcNames[i] << " in " << DLL_PATH << "." << std::endl;
    : return 1;
    : }
    : }
    :
    : [/code]:

    Thanks Lundin, that did the trick for the initialization.
    But do you have some hint on the normal calling convention like:

    bool (__stdcall* listener_OpenCom)(const char* port, const char* baudrate);

    How do you use the above mentioned function after the initialization ?

    Thanks a lot.

    Niffarella


  • LundinLundin Member Posts: 3,711
    Woah, this was an old thread.

    Simply call it as you would with any function:

    bool success = listener_OpenCom("COM1", "9600");

    That's why I wrote the #defines at the bottom of that post, they are there to remove the struct/union notation so that the function can be used more conveniently.
Sign In or Register to comment.