🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
6 messages
6 total messages Started by Mike Collins Thu, 14 Jun 2007 17:35
CALLBACK Hell
#1756
Author: Mike Collins
Date: Thu, 14 Jun 2007 17:35
52 lines
2687 bytes
Hi all, been having a right nightmare with a callback function that i'm 
trying to code / work with.

I'm using some third-party libraries written in pascal but i have a .h / 
.hpp for them.  I've created a wrapper class to deal with all the aspects of 
using these libraries.  However, one of the functions requires a callback 
procedure.  I need this callback to be able to 'see' my wrapper so i 
declared it thus:

// header
class TInjectController
{
private:
   TCriticalSection *csIPCCallBack;
   static void CALLBACK IPCProcessMsg(char *cName, void *pMsgBuf, unsigned 
int iMsgLen, void *pRtnBuf, unsigned int iRtnLen);
   ...

public:
   ...
   TInjectController();
   ~TInjectController();
};

extern TInjectController *InjectController;

// implimentation
void CALLBACK TInjectController::IPCProcessMsg(char *cName, void *pMsgBuf, 
unsigned int iMsgLen,
                                               void *pRtnBuf, unsigned int 
iRtnLen)
{
   InjectController->csIPCCallBack->Enter();
   ...
   InjectController->csIPCCallBack->Leave();
}

- I've declared the callback function as static and stuck in the extern 
reference at the bottom of the class.  I did this because it's the only way 
that i found that works in the past, with other callbacks i.e. EnumWindows 
etc...

However, on compile i get "[Linker Error] Unresolved external 
'_InjectController' referenced from C:\DOCUMENTS AND 
SETTINGS\ADMINISTRATOR\DESKTOP\TEST 
INJECTOR\TINJECTCONTROLLER\TINJECTCONTROLLER.OBJ"

If i remove the reference to the wrapper from within the callback, it works 
fine - but defeats the object and breaks my design.

Can anyone help me out here?  Also, can anyone tell me why the extern 
reference seems to be necessary >
Re: CALLBACK Hell
#1757
Author: Alan Bellingham
Date: Thu, 14 Jun 2007 16:38
54 lines
2739 bytes
"Mike Collins" <its@TheBottomOfThePost> wrote:

>extern TInjectController *InjectController;

Declaration.

>// implimentation
>void CALLBACK TInjectController::IPCProcessMsg(char *cName, void *pMsgBuf, 
>unsigned int iMsgLen,
>                                               void *pRtnBuf, unsigned int 
>iRtnLen)
>{
>   InjectController->csIPCCallBack->Enter();
>   ...
>   InjectController->csIPCCallBack->Leave();
>}

Use.

>- I've declared the callback function as static and stuck in the extern 
>reference at the bottom of the class.  I did this because it's the only way 
>that i found that works in the past, with other callbacks i.e. EnumWindows 
>etc...
>
>However, on compile i get "[Linker Error] Unresolved external 
>'_InjectController' referenced from C:\DOCUMENTS AND 
>SETTINGS\ADMINISTRATOR\DESKTOP\TEST 
>INJECTOR\TINJECTCONTROLLER\TINJECTCONTROLLER.OBJ"

Complaint about lack of definition. 

You're trying to call methods of an object that doesn't exist anywhere
in your source code. You told the compiler that it would exist in some
source file somewhere, but you don't seem to have actually declared it
anywhere.

>If i remove the reference to the wrapper from within the callback, it works 
>fine - but defeats the object and breaks my design.

Well, yes.

>Can anyone help me out here?  Also, can anyone tell me why the extern 
>reference seems to be necessary >

It's not necessary at all. But if you declare it *in the header* without
an extern, then it's a definition as well as a declaration, and it will
exist in every single source file that uses that header.

Do you initialise the pointer either?

Alan Bellingham
-- 
Team Browns
ACCU Conference 2008: 2-5 April 2008 - Oxford (probably), UK
Re: CALLBACK Hell
#1754
Author: Mike Collins
Date: Thu, 14 Jun 2007 17:44
8 lines
1331 bytes
Apologies for the last bit regarding the extern - obviously tells the 
compiler that there is a object of that type floating around some where..

But as for the rest, i'm still flummoxed...

"Mike Collins" <its@TheBottomOfThePost> wrote in message 
news:46716c33@newsgroups.borland.com...
> Hi all, been having a right nightmare with a callback 
Re: CALLBACK Hell
#1758
Author: Mike Collins
Date: Thu, 14 Jun 2007 18:29
29 lines
1978 bytes
I see what you are saying Alan.  however, in my main form, I have a pointer 
declared to this object, in the forms public section.  I assumed that this 
would be enough based on the extern i.e. indicates that there is a an object 
of this type somewhere.  I've tried including the Main.h in the wrapper 
class but I get some kind of circular reference compile error.

The only thing that appears to fix it is if i declare TInjectController 
*InjectController at the start of the TInjectController implementation - 
before the constructor.  Is this valid ?  Is there any issues with this? 
Can you suggest a better approach?

Thanks again,

Mike



"Alan Bellingham" <alan@lspace.org> wrote in message 
news:agr2731rl90vspqaucjmhlk7e2al16e028@4ax.com...
> "Mike Collins" <its@TheBottomOfThePost> wrote:
>
>>extern TInjectController *InjectController;
>
> Declaration.
>
>>// implimentation
>>void CALLBACK TInjectController::IPCProcessMsg(char *cName, void *pMsgBuf,
>>unsigned int iMsgLen,
>>                                               void *pRtnBuf, unsigned int
Re: CALLBACK Hell
#1760
Author: JD
Date: Thu, 14 Jun 2007 19:26
49 lines
2400 bytes
"Mike Collins" <its@TheBottomOfThePost> wrote:
>
> [...] I did this because it's the only way that i found that
> works in the past, with other callbacks i.e. EnumWindows 
> etc...

This has worked for me:

    protected:
        static  bool __stdcall EnumWindowsCallBack( HWND hWnd, LPARAM lParam );

//-------------------------------------------------------------
TSingleInstance *ThisSingleInstance = NULL;
//-------------------------------------------------------------
__fastcall TSingleInstance::TSingleInstance(TComponent* Owner) : TComponent(Owner)
{
    .....
    ThisSingleInstance = this;
    .....
}
//-------------------------------------------------------------
__fastcall TSingleInstance::~TSingleInstance()
{
    .....
    ThisSingleInstance = NULL;
}
//-------------------------------------------------------------
bool __stdcall TSingleInstance::EnumWindowsCallBack( HWND hWnd, LPARAM lParam )
{
    char WindowClassName[256] = { 0 };
    if( ::GetClassName(hWnd, WindowClassName, 255) )
      {
          if( stricmp(WindowClassName, reinterpret_cast<char*>(lParam)) == 0 )
            {
                if( hWnd != ThisSingleInstance->FParentForm->Handle )
                  {
                      ThisSingleInstance->hFirstInstance = hWnd;
                      return FALSE;
                  }
            }
      }
    return TRUE;
}
//-------------------------------------------------------------

Note the use of ThisSingleInstance in the CallBack.

~ JD
Re: CALLBACK Hell
#1779
Author: Mike Collins
Date: Mon, 18 Jun 2007 23:19
7 lines
1258 bytes
Cheers JD, think the problem was that i was creating the callback in a pure 
class and my pointer to it was in a TForm that created the class - all 
working now though


"JD" <nospam@nospam.com> wrote in message 
news:46719667@newsgroups.borland.com... 
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads