• Welcome to Valhalla Legends Archive.
 

GetProcAddress throws error 127 (ERROR_PROC_NOT_FOUND) - (**RESOLVED**)

Started by Dyndrilliac, February 07, 2009, 01:53 PM

Previous topic - Next topic

Dyndrilliac

Edit: Wow, I just realized I totally forgot to tell the linker I even _had_ a *.def file... :facepalm:

So I've been putting the finishing touches on a new plugin feature for a project of mine, but GetProcAddress keeps failing when it shouldn't (at least, as far as I can tell). The system I'm using to implement the plugin functionality is as follows. My main project DLL loads all the dll's in the plugins directory (which is determined on-the-fly) and keeps track of their handles. Then, once loaded into the same address space, the plugins access the main DLL and retrieve a handle to it's base address. Then, they call GetProcAddress to obtain the addresses for some of it's API functions, the most vital of which allows the plugin to register data (such as the name of the plugin, it's author, it's version, and some function pointers) with my application so that it can send the plugins notifications of events (such as when a key has been pressed on the keyboard).

Here's the code for the plugins calls to GetProcAddress:/*
Grab addresses for API's we can expect to be available.
*/

const HMODULE EXODUS_HANDLE = GetModuleHandleA("EXODUS.DLL");
if (!EXODUS_HANDLE) {
ReportError("Error! Could not locate the module handle for Exodus!");
return;
}

char TempBuffer[MAX_PATH] = {NULL};

ExRegPluginInfo = (EXREGPLUGININFO)GetProcAddress(EXODUS_HANDLE,"ExRegPluginInfo");
if (!ExRegPluginInfo) {
wsprintfA(TempBuffer,"Error! Could not locate the expected API: ExRegPluginInfo\nError Code: %u",GetLastError());
ReportError(TempBuffer);
return;
}
WriteMemory = (WRITEMEMORY)GetProcAddress(EXODUS_HANDLE,"WriteMemory");
if (!WriteMemory) {
wsprintfA(TempBuffer,"Error! Could not locate the expected API: WriteMemory\nError Code: %u",GetLastError());
ReportError(TempBuffer);
return;
}
WriteDetour = (WRITEDETOUR)GetProcAddress(EXODUS_HANDLE,"WriteDetour");
if (!WriteDetour) {
wsprintfA(TempBuffer,"Error! Could not locate the expected API: WriteDetour\nError Code: %u",GetLastError());
ReportError(TempBuffer);
return;
}
InjectDLL = (INJECTDLL)GetProcAddress(EXODUS_HANDLE,"InjectDLL");
if (!InjectDLL) {
wsprintfA(TempBuffer,"Error! Could not locate the expected API: InjectDLL\nError Code: %u",GetLastError());
ReportError(TempBuffer);
return;
}

/*
Register the plugin's information with Exodus here.
*/

ExRegPluginInfo(&myEXPIS);
My typedefs and function pointer stuff:/*
Function pointer type definitions (delegate types for you .NET programmers).
*/

typedef bool (WINAPI *EXREGPLUGININFO)(EXPLUGINFOSTRUCT*);
typedef DWORD (WINAPI *WRITEDETOUR)(const DWORD,const DWORD,const DWORD,const bool);
typedef DWORD (WINAPI *WRITEMEMORY)(const DWORD,const DWORD,const DWORD);
typedef bool (WINAPI *INJECTDLL)(PCSTR,PCSTR,const BYTE);

/*
Function pointers (instances of delegates).
*/

static EXREGPLUGININFO ExRegPluginInfo;
static WRITEDETOUR WriteDetour;
static WRITEMEMORY WriteMemory;
static INJECTDLL InjectDLL;
I've tried identifying the function by both name and ordinal, and I still get the same result regardless. Here is how I've got the API exposed (Exodus.def):LIBRARY "Exodus"
EXPORTS
InjectDLL @1
WriteDetour @2
WriteMemory @3
ExRegPluginInfo @4
And here is what they're prototypes look like:extern "C" bool WINAPI ExRegPluginInfo(EXPLUGINFOSTRUCT *pEXPIS);
extern "C" DWORD WINAPI WriteDetour(const DWORD dwSource,const DWORD dwDestination,const DWORD dwPadSize,const bool bType);
extern "C" DWORD WINAPI WriteMemory(const DWORD dwDestination,const DWORD dwSource,const DWORD dwDataLength);
extern "C" bool WINAPI InjectDLL(PCSTR szFilename, PCSTR szIdentifier, const BYTE bFlag);
My structure (EXPLUGINFOSTRUCT) is exactly the same for both the main DLL and my test plugin:struct EXPLUGINFOSTRUCT {
PCSTR szPluginName; // plugin name
PCSTR szPluginAuthor; // plugin author
BYTE  dwVersion[3];  // The version is three bytes in this order [major version - minor version - revision]
DWORD (WINAPI *fxnKeyboardEvent)(int,WPARAM,LPARAM); // Keyboard event func ptr
};
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

MyndFyre

I've sometimes had trouble getting exports to work correctly (even with a .def file attached) when not using __declspec(dllexport).  Unfortunately that's the only insight I can offer - are you using VC++?

You might consider macro-ing your export:

#define PLUGIN_EXPORT __declspec(dllexport) extern "C" WINAPI


Then your exports become:

PLUGIN_EXPORT bool ExRegPluginInfo(EXPLUGINFOSTRUCT *pEXPIS);


*shrug*
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.