This is my first post! I can’t figure out how to modify/cast the return address obtained from the Windows Api function GetProcAddress() without using a typedef. I’m aware that using a typedef is the standard way to do this, but one should be able to do it without a typedef, shouldn’t one???

I’ll provide a very simple example below for anyone to use if someone would be willing to instruct me on this. Lets make a simple wrapper around the printf function and export it from a dll like so….

//dllWork.cpp
#include <windows.h>
#include <stdio.h>

extern "C" __declspec(dllexport) void Prt(char* msg)
{
 printf("%s\n",msg);
}

This can be compiled with the Microsoft C++ compiler like so…

>cl dllWork.cpp /LD

All it does when called is output to the console the asciiz string passed to it with printf. Below is a host program to explicitely load it and obtain the address of the Prt function with GetProcAddress()…

//Begin  dllHost.cpp
#include <windows.h>
#include <stdlib.h>
typedef void (*FNPTR)(char*);                 <<<note typedef!!!

int main(void)
{
 char szMsg[]="Hello, World!";
 HINSTANCE hIns;
 FNPTR pFn;
 
 hIns=LoadLibrary("dllWork.dll");
 if(hIns)
 {
    pFn=(FNPTR)GetProcAddress(hIns,"Prt");    <<<note use of typedef
    pFn(szMsg);    
    FreeLibrary(hIns);
 }
 system("PAUSE");
  
 return 0;
}

>cl dllHost.cpp

As you can see, it uses a typedef in the customary manner to obtain a usable function pointer out of GetProcAddress(). The program calls Prt in the dll passing it the asciiz string “Hello, World!”.

My question is, “How can this be done without typedef?” I’ve tried for hours, and the only conclusion I can come to is that typedef is magic or witchcraft and beyond the ken of any human understanding. Would anyone be willing to prove me wrong? Honestly, I've been trying to do this for hours and can't get it.

PS Wow!!! I love your code tags and syntax highlighting!!!

This compiles without error -- did not attempt to run it. I actually got a hint how to do it from the compiler's error message : error C2440: '=' : cannot convert from 'FARPROC' to 'void (__cdecl *)(char *)'

int main(void)
{
 char szMsg[]="Hello, World!";
 HINSTANCE hIns;
 void (*pFn)(char*) = 0; 
 hIns=LoadLibrary("dllWork.dll");
 if(hIns)
 {
    pFn = (void (__cdecl *)(char *))GetProcAddress(hIns,"Prt");
    pFn(szMsg);    
    FreeLibrary(hIns);
 }
 system("PAUSE");
  
 return 0;
}
Comments
Really no one upvotes this?

That did it AncientDragon! I knew the key was informing the compiler it was a function call that needed to be set up, not simply a cast, but I couldn't come up with it. I like to fully understand things, you know?

Just in case you're interested, this is what it looks like in PowerBASIC, which is another compiler I use a lot...

#Compile Exe
#Dim All
#Include "Win32Api.inc"
Declare Sub ptrFx()

Function PBMain() As Long
  Local hInstance, dwAddr As Dword

  hInstance=LoadLibrary("DllTest.dll")
  If hInstance Then
     dwAddr=GetProcAddress(hInstance,"Fx")
     Call Dword dwAddr Using ptrFx
     FreeLibrary(hInstance)
  End If

  PBMain=0
End Function

In the above code note 'Declare Sub ptrFx' In the body of PBMain and see how it is used. Call Dword is a PowerBASIC reserved word used to call a function at some/any specific known address. The 'Using' part of the verb tells the compiler what the function looks like so it can set up the function call mechanism. That was really the missing ingredient which you provided for me, that is, some way to let the compiler know its a cdecl function and so on.

Thanks a lot. I'll be studying that!

Fred

This question has already been answered. Start a new discussion instead.