im quite confused on how typedef int (__cdecl *MYPROC)(LPWSTR);
works exactly? how do you typedef a function? any explanation is greatly appreciated! thx :D

// A simple program that uses LoadLibrary and 
// GetProcAddress to access myPuts from Myputs.dll. 

#include <windows.h> 
#include <stdio.h> 

typedef int (__cdecl *MYPROC)(LPWSTR); 

VOID main(VOID) 
{ 
HINSTANCE hinstLib; 
MYPROC ProcAdd; 
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; 

// Get a handle to the DLL module.

hinstLib = LoadLibrary(TEXT("MyPuts.dll")); 

// If the handle is valid, try to get the function address.

if (hinstLib != NULL) 
{ 
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts"); 

// If the function address is valid, call the function.

if (NULL != ProcAdd) 
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd) (L"Message sent to the DLL function\n"); 
}
// Free the DLL module.

fFreeResult = FreeLibrary(hinstLib); 
} 

// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess) 
printf("Message printed from executable\n"); 
}

Dani AI

Generated

As already said, that line defines a named type for a function-pointer, not a function itself. and covered the basic shape and calling-convention point; here are practical, actionable notes and a few safe patterns you can apply right away.

// DLL side: export with C linkage so the name is predictable
extern "C" __declspec(dllexport) int __cdecl myPutsW(const wchar_t* s) {
    // implementation...
    return 0;
}

// Host side: prefer a clear alias and a reinterpret_cast from GetProcAddress
using MyPutsFn = int(__cdecl*)(const wchar_t*);

HMODULE h = LoadLibraryW(L"MyPuts.dll");
if (h) {
    auto f = reinterpret_cast<MyPutsFn>(GetProcAddress(h, "myPutsW"));
    if (f) f(L"hello");
    FreeLibrary(h);
}

Troubleshooting and gotchas

  • If GetProcAddress returns NULL call GetLastError. Often the export name is missing or mangled; use extern "C" or inspect exports (dumpbin /exports or a dependency tool).
  • Calling-convention mismatch will often crash (stack corruption) even though GetProcAddress returned a non-NULL pointer. Match cdecl / stdcall / WINAPI exactly. On x64 Windows those qualifiers are ignored (x64 has a single ABI).
  • Watch string constness: use const wchar_t* (LPCWSTR) if the function does not modify the string.
  • Avoid crossing CRT boundaries with heap ownership (do not free memory in the caller that was malloc'd in the DLL unless you design shared alloc/free helpers).

Modern alternatives

  • In C++11+ prefer using for type aliases (shown above). For higher-level callback storage, wrap the raw pointer in std::function or a small adapter so calling code is safer and easier to test.

Summary
As linked and as noted, calling conventions matter; as said, you are naming a pointer type. Export the function with predictable linkage, use a clear alias, check for errors, and prefer modern C++ wrappers for safety.

Recommended Answers

All 4 Replies

This might help.
Upvote my post if they help.

how do you typedef a function?

You don't. The code you posted is a typedef for a pointer to a function.

Yes that is indeed a pointer to a function, a named one.

typedef void (*funcPtrType)(int someParam);
funcPtrType pSomeFunc = nullptr;
pSomeFunc = &someFuncWithTheRightParamsAndReturnType;
pSomeFunc(1000);

The typedef that you have shown is a typedef for a "function pointer" type. The format is a bit different than other "normal" typedefs. Here would be the simple format of such a typedef:

[B]typedef[/B] [I]return_type[/I] ([[I]calling_convention[/I]] *[B]identifier[/B]) ( [I]parameter_list[/I] );

This means that the following function signature (or prototype) would correspond to the function pointer type defined below:

//function signature (i.e. declaration or prototype):
int myFunction( char* s, int count);
//corresponding function pointer typedef:
typedef int (*myFunctionPtrType) (char*,int);

Which would allow it to be used as such:

int myFunction( char* s, int count) {
  //do something..
  return 0;
};

int main() {
  myFunctionPtrType p = &myFunction; //notice the syntax here, taking the address of myFunction.

  //now p can be called as if it was a function:
  char s[20];
  int result = p(s,20); //the call syntax is as if it was function.
  std::cout << "The result of calling p was: " << result << std::endl;
};

In the example you posted, the "__cdecl" keyword is simply the calling convention of the function (like __stdcall or __fastcall). These are important when using function pointers across different modules (and possibly different original programming languages). For instance, __cdecl is the default C calling convention and is supported by many other languages, and __stdcall is a standard calling convention that is mostly used by Win32 API to make it essentially callable from any programming language.

There are several other variants of this basic concept of "pointing to a function", which include pointer to member functions, function objects, and function types. Boost.Bind and Boost.Function are libraries that exploit those very well (and, with basic knowledge of templates, they are generally easier to use than classic function pointers and the like).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.