Function Pointer Question

Started by
3 comments, last by Oluseyi 19 years, 2 months ago
I'm having a problem running this from a DLL, it says unresolved external symbol, I posted something like this similar before, but I thought i'd make it more general here is my 'DLL Server'? (is that whats it's called? correct me if i'm wrong..the dll code)

//dllmain.cpp

//the function pointer
void (*FuncPointer)(int i);

__declspec(dllexport)
void SetFunction(void (*func)(int))
{
FuncPointer = func;
}

__declspec(dllexport)
void CallFunction(int i)
{
FuncPointer(i);
}

and then here is my DLL Client (again, correct me if these names are wrong..i have no idea..this is the code that uses the dll

//main.cpp
#include "dll.h"
#pragma comment(lib, "dll.lib")

void Function(int i);

int main()
{
SetFunction(Function);
CallFunction( 5 );

return 0;
}

void Function(int i)
{
cout << i;
}

the dll server compiles fine. The client screws up on the linking phase giving me these errors..

main.obj : error LNK2019: unresolved external symbol "void __cdecl CallFunc(int)" (?CallFunc@@YAXH@Z) referenced in function _main
main.obj : error LNK2019: unresolved external symbol "void __cdecl SetFunc(void (__cdecl*)(int))" (?SetFunc@@YAXP6AXH@Z@Z) referenced in function _main
LIBCMTD.lib(wincrt0.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function _WinMainCRTStartup

hmm? I was told it that I should do something with __declspec(dllimport) but I don't really understand where to put that or why, how..yeah..so..any help would be appreciated
Advertisement
Well here is a great resource for function pointers. Your use of them will not work the way you are doing it. I'd say give that page a read first, then can you explain what you are 'trying' to do. If by chance you are trying to do plugin programming, take a look at this FlipCode article as well, but still get back to this thread.

- Drew
Thank you for your response Drew Benton, I will definatly read both those articles, but just to explain better what i'm trying to do is..

I want to be able to have a function in my dll, i guess...use a function created by the end-user program..I've got this to work without the use of a dll and using a static library instead, so that's why i thought my problem was with the dll (i don't know a whole lot about them)

the reason for doing this is I want my application to be able to handle different events differently so for example in my dll I code something like this

if (Event == BOX_CLOSED)FunctionPointer(BOX_CLOSED)

then in the application that uses the dll...i can actually handle that specific event however I want
//this line makes it so the "FunctionPointer" function up above actually points to this new functionSetEventHandler(HandleEvent);void HandleEvent(int Message){if (Message == BOX_CLOSED)MessageBox(0, "Box Closed", 0 , 0);}

I hope that makes it a bit more clear? maybe after reading those articles i can correct myself a bit

Thanks again
What does dll.h look like? Does it prototype SetFunction() and CallFunction()?
The contents should be something like this:
#ifdef DLL_EXPORTS#   define MYDLL_LINKAGE __declspec(dllexport)#else#   define MYDLL_LINKAGE __declspec(dllimport)#endifMYDLL_LINKAGE void SetFunction(void (*func)(int));MYDLL_LINKAGE void CallFunction(int i)

And then dll.cpp should be:
//dllmain.cpp//the function pointervoid (*FuncPointer)(int i);MYDLL_LINKAGE void SetFunction(void (*func)(int)){FuncPointer = func;}MYDLL_LINKAGE void CallFunction(int i){FuncPointer(i);}

When you're building your DLL, you should define DLL_EXPORTS somewhere (preferably in the preprocessor settings if you're using MSVC++).
If this is defined, then the compiler will flag the functions as exported from the DLL.
When you build your main application, DLL_EXPORTS won't be defined, so the compiler will flag the functions as being imported from a DLL. I'm not even entirely sure you *need* to say they're imported from a DLL, you could perhaps get away with not using __declspec(dllimport), but it's not a good idea.

Also, your last linker error is because you created a Win32 application instead of a Win32 console application. Either re-create the project as a console app, or change your int main() function to int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) and #include windows.h.
Quote:Original post by kag1
main.obj : error LNK2019: unresolved external symbol "void __cdecl CallFunc(int)" (?CallFunc@@YAXH@Z) referenced in function _main
main.obj : error LNK2019: unresolved external symbol "void __cdecl SetFunc(void (__cdecl*)(int))" (?SetFunc@@YAXP6AXH@Z@Z) referenced in function _main
These two errors (by the way, all MSVC errors are detailed in MSDN, but local installs and online: LNK2019) indicate that the linker can not find the appropriate function bodies. Since you speak of DLLs but didn't clarify whether you had created a static import library (though your code does link in a dll.lib; is that your import lib?), I think you should read up on LoadLibrary and GetProcAddress. Essentially, you will need to directly (or in your import library) load the DLL, then retrieve the addresses of the functions from the DLL via GetProcAddress, which you'll store in function pointers of the same name, pretty much as follows:
(void *)SetFunction((void *)func(int));(void *)CallFunction(int);HMODULE hDLL = LoadLibrary("DllName.dll");SetFunction = GetProcAddress(hDLL, "SetFunction");CallFunction = GetProcAddress(hDLL, "CallFunction");...FreeLibrary(hDLL);...


Quote:LIBCMTD.lib(wincrt0.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function _WinMainCRTStartup
You have a mismatch between project type and entry point. In this case, you appear to have set up a Win32 project, but are using main as your entry point instead of WinMain.

Happy hacking.

This topic is closed to new replies.

Advertisement