• 15
• 15
• 11
• 9
• 10

# [Resolved] Can't Load Functions from a DLL

This topic is 3831 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I've written a simple DLL using Borland Developer Studio 2006 C++ Builder. I've also written an application that does nothing other than a dynamic load of the DLL and attempt to access a single function. Everything compiles without errors or warnings, the DLL appears to load properly, but I cannot load the function. I have looked in books and read what I could find on the internet pertaining to creating and using DLLs dynamically and everything seems to be fine. Could some of you DLL experts take a look at the code below and tell me why the function itself cannot be accessed? The DLL header file:
/* dllproj1.h */
extern "C" char* __declspec(dllexport) dllString1(void);


The DLL source CPP:
/* dllproj1.cpp */
#include <windows.h>
#include <dllproj1.h>

#pragma argsused

int WINAPI DllEntryPoint1(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
char* dllString1(void){
return "This is from DLL 1";
}


The applicable portion of the application header:
...
private:	// User declarations
HMODULE hDll;
typedef char* (__declspec(dllimport) *LPFNC_DLLSTRING) (void);
LPFNC_DLLSTRING lpfnc_dllstring;
...


The applicable portion of the application source .CPP :
void __fastcall TForm1::Button1Click(TObject *Sender)
{
char* szBuffer = "Operation aborted";
//Load the specific library
if(!hDll){
return;
}else{
}

lpfnc_dllstring = (LPFNC_DLLSTRING)(GetProcAddress(hDll, "_dllString1"));
if(lpfnc_dllstring){

}else{
FreeLibrary(hDll);
return;
}
//Call the function from the DLL

szBuffer = lpfnc_dllstring();

Memo1->Text = szBuffer;
}


I've actually tried many different variations on the code above but this is the latest version. The function pointer lpfnc_dllstring always returns "Function NOT found". I've never been able find the function from the DLL. Any suggestions? Thanks in advance. [Edited by - lostincpp on September 27, 2007 4:48:46 PM]

"_dllString1"
Should be:
"dllString1"
Surely?

##### Share on other sites
Tried that as well. Changed it when I found a note in the Borland Help that said C++ Builder automatically puts an underscore in front of the name when it compiles the DLL. But I tried it again at your suggestion and have the same results.

That was my original suspicion, that some type of name-mangling was going on during the compile process. Know of any way that I can check what the actual compiled name would be?

##### Share on other sites
Are you using a DEF file? There is a common misconception among C++ programmers that the __declspec(dllexport) qualifier is a substitute for a library definition file, but this isn't the case. Unless you provide such a set of definitions, the compiler is free to decorate your function names to make things easier for the linker. By 'decorate', I (along with everyone else) mean appending various symbols to the name to describe its stack footprint and calling convention (e.g. msvcr70.dll's exception() ends up looking like ??_Gexception@@UAEPAXI@Z).

This may, or may not be your problem. You can find out for sure by viewing the DLL in a PE editor (or dumpbin, or the MS Dependency Walker). If this turns out to be the case, you have two options. Either use the decorated names with LoadLibrary, which is a bad idea for several reasons, or recompile the DLL with an appropriate definition file.

##### Share on other sites
I used Dependency Walker and found out that the function was not even being exported. So, I started the project over and kept the DLL files to a minimum.

Here's the final DLL source file. I eliminated the header file. Nothing was changed in the application file other than the name of the actual function as it was finally exported.

#include <windows.h>#pragma argsusedint WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved){	return 1;}//---------------------------------------------------------------------------extern "C"{    char* __declspec(dllexport) dllString1(void)    {	return "From DLL 1";    }} // end of extern "C" block

For anyone who doesn't know and might be reading this for a similar problem:

__declspec(dllexport) should appear just before the function name that you intend to export.

extern "C" prevents your exported function names from being C++ mangled so that the exported name will be the actual name of your function, except where your compiler might be adding characters.

If you are using a Borland compiler, an underscore is inserted prior to the function name. You can turn that option off so that the underscore isn't generated.

I did not need a .DEF file. I'm not certain if its because I was using dynamic linking or because I was using __declspec(dllexport). Information I could obtain from the internet wasn't clear about when to use .DEF and when not.