
C++ function pointers versus C function pointer problem
Quote:
> Hi all,
> I am having a bit of a problem with function pointer declarations in C
> and
> C++. My library has to work in both C and C++. Now, the following .h
> and
> .cpp files compile and work under a CPP file, but not under a C file.
> The
> function call back pointer in the header seems to be one of the main
> culprits.
The problem is not the functions but the special namespace around them.
BTW, it is a little known fact of C(++) that callbacks should be
'static'. This proves the only way another "module" gets its paws on
them is by passing a pointer to a function. Your strategy is okay if
someone outside this translation unit really needs the functions by
name.
Quote:
> <<<nitrodll.h>>>
> #ifndef __AFXWIN_H__
> #error include 'stdafx.h' before including this file for PCH
> #endif
> #define STDCALL __stdcall
> typedef BOOL (*STDCALL TSortStatusProc)(int *pos, void *userData);
I'm the C compiler... Okay, I can handle BOOL and STDCALL and stuff...
Quote:
> extern "C" {
Eeek! what's that? That's not C!
Quote:
> int STDCALL Sort(LPCSTR cmdStmt, LPSTR errorStr, int errorLen,
> TSortStatusProc statusProc, void *userData);
> int STDCALL SortMem(void *memBlock, int memSize, LPSTR cmdStmt,
> LPSTR errorStr, int errorLen);
> int STDCALL SortMemByPtrs(void *memPtrs, int numRecs, LPCSTR cmdStmt,
> LPSTR errorStr, int errorLen);
> }
> <<<end nitrodll.h>>>
> <<<begin nitrodll.cpp>>>
> #include "stdafx.h"
> #include "nitrodll.h"
> #include <winbase.h>
> #ifdef _DEBUG
> #define new DEBUG_NEW
> #undef THIS_FILE
> static char THIS_FILE[] = __FILE__;
> #endif
> // Procedure pointers.
> typedef int ( far Pascal *TDEFSort)
> (LPCSTR, LPSTR, int, TSortStatusProc, LPVOID );
> typedef int ( far PASCAL *TDEFSortMem)
> (LPVOID, int, LPCSTR , LPSTR , int );
> typedef int ( far PASCAL *TDEFSortMemPtrs)
> (LPVOID, int, LPCSTR , LPSTR , int );
> static TDEFSort dynSort = 0 ;
> static TDEFSortMem dynSortMem = 0 ;
> static TDEFSortMemPtrs dynSortMemPtrs = 0 ;
> int STDCALL Sort(LPCSTR cmdStmt, LPSTR errorStr, int errorLen,
> TSortStatusProc statusProc, void
> *userData)
> {
> HMODULE hSort = 0;
> int tmpInt = 0;
> hSort = LoadLibrary("nitro.dll");
> dynSort = (TDEFSort) GetProcAddress(hSort,"Sort");
> tmpInt = dynSort(cmdStmt, errorStr, errorLen, statusProc,
> userData);
> FreeLibrary(hSort);
> return tmpInt;
> }
> int STDCALL SortMem(void *memBlock, int memSize, LPSTR cmdStmt,
> LPSTR errorStr, int errorLen)
> {
> HMODULE hSort = 0;
> int tmpInt = 0;
> hSort = LoadLibrary("nitro.dll");
> dynSortMem = (TDEFSortMem) GetProcAddress(hSort,"SortMem");
> tmpInt = dynSortMem(memBlock, memSize, cmdStmt, errorStr,
> errorLen);
> FreeLibrary(hSort);
> return tmpInt;
> }
> int STDCALL SortMemByPtrs(void *memPtrs, int numRecs, LPCSTR cmdStmt,
> LPSTR errorStr, int errorLen)
> {
In C++, this needs the same linkage as its declaration in the header.
Therefore you need 'extern "C"' here too.
extern "C" int STDCALL SortMemByPtrs(void *memPtrs, int numRecs,
LPCSTR ...
Finally, to hid this thing from the C compiler, wrap it like this:
#ifdef __cplusplus
extern "C"
#endif
To hide it in the header,
#ifdef __cplusplus
extern "C" {
#endif
wrap the end-of-block the same way.
<snip>
-- Phlip
====== http://users.deltanet.com/~tegan/home.html ======
-- A card-carrying Microsoft LVP
- Least Valuable Professional --