Why GetProcAddress doesn't work? - c++

First, I create a simple dll called SimpleDll.dll, its head file:
// SimpleDll.h
#ifdef MYLIBAPI
#else
#define MYLIBAPI __declspec(dllimport)
#endif
MYLIBAPI int Add(int a. int b);
its source code:
// SimpleDll.c
#include <windows.h>
#define MYLIBAPI __declspec(dllexport)
#include "SimpleDll.h"
int Add(int a, int b)
{
return a + b;
}
Then I call it in another project, and it works fine:
// TestSimpleDll.c
#include "stdafx.h"
#include <windows.h>
#include "SimpleDll.h"
#pragma comment(lib, "SimpleDll.lib")
int _tmain(int argc, _TCHAR* argv[])
{
printf("%d", Add(10, 30)); // Give the expected result 40
return 0;
}
However, when I call GetProcAddress to get it's address, it doesn't work!
// TestSimpleDll2.c
#include "stdafx.h"
#include <windows.h>
#include "SimpleDll.h"
#pragma comment(lib, "SimpleDll.lib")
int _tmain(int argc, _TCHAR* argv[])
{
printf("%d", Add(10, 30)); // Give the expected result 40
HMODULE hModule = GetModuleHandleA("SimpleDll.dll"); // hModule is found
PROC add_proc = GetProcAddress(hModule, "Add"); // but Add is not found !
// add_proc is NULL!
return 0;
}
Thanks for your help. (PS: I use VS2010 on Windows7)
Update:
This is what the depedency walker show for the SimpleDll.dll file:

You should use a .def file if you want to export the name for GetProcAddress. Otherwise you will have to deal with c++ name mangling and with symbol decorations.
You can avoid mangling by declaring your function as extern "C", but the only way to avoid decorations is to use a .DEF file.
One more thing - in Dependency walker - use F10 to toggle between decorated and undecorated names.

Dependency Walker is an excellent tool for troubleshooting DLL issues like this.
I'm assuming you are compiling the DLL as C code. Otherwise, C++ performs name mangling that would cause problems.
To avoid name mangling simply wrap the export definition in extern "C".
extern "C" {
MYLIBAPI int Add(int a. int b);
}

Related

Is it possible to open URL in C++ WITHOUT using <windows.h>?

I found it a little tricky that some compiler can't run the <windows.h> header file. Is it possible to open an URL in C++ without using <windows.h> ?
Here's my code, but using <windows.h>
#include <windows.h>
#include <shellapi.h>
using namespace std;
int main(){
ShellExecute(NULL,NULL,"https://ssur.cc/Easy-Way-To-Open-URL-In-CPP",NULL,NULL,SW_SHOW );
return 0;
}
You could just forward declare the function in question and let the linker handle it.
But if your compiler has issues with windows.h it will probably not support all Windows platforms/architectures. But assuming the calling-convention used by the compiler just happens to match you can do something like this:
typedef void* M_HINSTANCE;
typedef void* M_HWND;
#define M_SW_SHOW 5
// should be __stdcall , but if your compiler has trouble with windows.h, then it will probably also have trouble with __stdcall
extern "C" M_HINSTANCE ShellExecuteA(M_HWND hwnd,
const char* lpOperation,
const char* lpFile,
const char* lpParameters,const char* lpDirectory,
int nShowCmd
);
int main(){
ShellExecuteA(0,0,"https://ssur.cc/Easy-Way-To-Open-URL-In-CPP",0,0,M_SW_SHOW );
return 0;
}
You will still need to link to Shell32.lib and like I mentioned you might get linker errors on some platforms for mismatching calling conventions.
Alternatively you can try to start the shell as a generic process like
#include <cstdlib>
int main(){
std::system("cmd.exe /c start https://ssur.cc/Easy-Way-To-Open-URL-In-CPP");
// or something like:
// std::system("explorer.exe https://ssur.cc/Easy-Way-To-Open-URL-In-CPP");
// or on some other non-windows platforms:
// std::system("open https://ssur.cc/Easy-Way-To-Open-URL-In-CPP");
return 0;
}

GetProcAddress return error code 127 in c++?

I have a dll and header file. Now I am creating a console application using vs2015. and load this library. But while getting GetProcAddress of function. It is always returning NULL. Here is my code.
Contents of header file (test.h) (This header file is only for your reference)
#ifdef APPLYDLL_EXPORTS
#define APPLYDLL_API __declspec(dllexport)
#else
#ifdef BUILD_EXE
#define APPLYDLL_API
#else
#define APPLYDLL_API __declspec(dllimport)
#endif
#endif
#include <string>
#include <winerror.h>
APPLYDLL_API HRESULT ApplySettings(std::string input);
Contents of console application (cpp file)
#include "stdafx.h"
#include <Windows.h>
#include <string>
using namespace std;
//Define the function prototype
typedef HRESULT(CALLBACK* ApplySettings)(std::string);
int main()
{
HINSTANCE hLib = LoadLibrary(TEXT("ApplyTool.dll"));
if (NULL != hLib)
{
//Get pointer to our function using GetProcAddress:
ApplySettings applySettings = (ApplySettings)GetProcAddress(hLib,"ApplySettings");
DWORD errorcode=GetLastError(); //errorcode 127, Procedure not Found
}
return 0;
}
I don't know, Where I am doing silly mistake.
Someone please help me.
Thanks in adv.
I Agree with CrazyCoder, check the DLL using Dependency Walker with that function name.
and try to change define as like below,
#define APPLYDLL_API __declspec(dllexport)
to
#define APPLYDLL_API extern "C" __declspec( dllexport )
Thanks, Jake.

Using SDL2_gfx issues using C++

When I use SDL2_gfx with the common.c /common.h files that are included with it, and then use the cpp instead of c extension using VS201X, I get the LNK2019: unresolved external symbol _SDL_main
What that means is if I change the file containing main to test.c, it compiles. When I change it back to text.cpp it fails to compile.
I think that indicates that it only works as C, and not C++.
Below is the code I copied from SDL2_gfxPrimitives.c (Spaces added so they would show up):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include "common.h"
#include "SDL2_gfxPrimitives.h"
static CommonState *state;
int main(int argc, char* argv[])
{
/* Initialize test framework */
state = CommonCreateState(argv, SDL_INIT_VIDEO);
return 1;
}
I need to use the library in C++ but it seems I don't know enough to figure out how. Any help would be appreciated, I've spent two days attempting to figure this out.
This is a little bit of a gotcha for SDL.
What it does is #define main SDL_main
This renames int main(int argc, char *argv[]) into int SDL_main(int argc, char *argv[]).
In order to use it, SDL wants an unmangled SDL_main to link against, and because you simply renamed the test.c -> test.cpp, you didn't add the code to cause this to happen.
It's described in the documentation:
The application's main() function must be called with C linkage, and should be declared like this:
#ifdef __cplusplus
extern "C"
#endif
int main(int argc, char *argv[])
{
}
so if you put the:
#ifdef __cplusplus
extern "C"
#endif
immediately before the declaration of the main function, it should link correctly.
I figured out a fix. I had to put this code in. Also, the answer above is good. Now I know why it happens too. Google did not find that document.
extern "C"
{
#include "common.h"
}

Using .c and .cpp files in Visual Studio at the same time

Trying to figure out how to get an application to compile that uses both C and C++ files. Not the entire code, but enough to get the idea:
main.cpp:
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "one.h"
#include "two.h"
int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hInst2, LPSTR lpCmdLine, int nShowCmd) {
FunctionOne();
FunctionTwo();
}
one.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <gdiplus.h>
#include <gdiplusflat.h>
using namespace Gdiplus;
using namespace Gdiplus::DllExports;
int FunctionOne() {
}
two.c
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int FunctionTwo() {
}
The header files contain only definitions for those functions.
Now, if I compile this with a main.cpp, I get an "unresolved external symbol" for FunctionTwo. If I compile this with a main.c, I get the same thing for FunctionOne. Is this even possible, and if so, how would I set up the project to compile properly (Visual Studio 2010)?
It compiles fine if I comment out the alternate function depending on the extension for main.
Thanks!
The problem is two.h, it almost certainly wasn't written to allow a C++ compiler to properly compile the C function prototype. You'll want to take advantage of the predefined __cplusplus macro, like this:
two.h:
#ifdef __cplusplus
extern "C" {
#endif
int FunctionTwo();
// etc...
#ifdef __cplusplus
}
#endif
Lovely macro soup ;) If the header is pre-baked and never saw a C++ compiler before then do this in your .cpp source code file:
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "one.h"
extern "C" {
#include "two.h"
}
Some programmers name their header files .hpp if they contain C++ declarations and .h if they contain C declarations. That's a pretty good practice I personally favor. So does the Boost team. It didn't otherwise set the world on fire.
C++ does name-mangling to support function overloading while C does not. You will have to mark your function as extern "C" to prevent name mangling.
// main.cpp
extern "C" int FunctionTwo();
.. the rest ..
// two.c
extern "C" int FunctionTwo() {
// stuff
}
See http://www.parashift.com/c++-faq/mixing-c-and-cpp.html for more information on mixing C and C++.

GetCurrentConsoleFont not declared in scope, what I do wrong?

at the beginning I have:
#include <sstream>
#include <iostream>
#include <stdio.h>
#include <iomanip>
#include <string>
#define _WIN32_WINNT 0x500 //tells that this is win 2000 or higher, without GetConsoleWindow would not work
#include <windows.h>
using namespace std;
int main() {
PCONSOLE_FONT_INFO lpConsoleCurrentFont;
GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), false, lpConsoleCurrentFont);
return 0;
}
And undocumented function SetConsoleFont works, but GetCurrentConsoleFont fails at compilation saying that it was not declared in this scope.
-- edit: changed to self sustained code.
GetCurrentConsoleFont is exported on NT4+ at least, the MinGW headers must be wrong.
Try adding this code after your #include's:
#ifdef __cplusplus
extern "C" {
#endif
BOOL WINAPI GetCurrentConsoleFont(HANDLE hConsoleOutput,BOOL bMaximumWindow,PCONSOLE_FONT_INFO lpConsoleCurrentFont);
#ifdef __cplusplus
}
#endif
Your code is also wrong, it should be:
CONSOLE_FONT_INFO ConsoleFontInfo;
GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), false, &ConsoleFontInfo);
(Any time you see PSOMETYPE as a parameter you usually allocate a SOMETYPE struct on the stack and pass a pointer to this struct as the parameter)
Hans comment above is correct. GetCurrentConsoleFont is not defined in wincon.h. Add the following lines to wincon.h to get this functionality:
BOOL WINAPI GetCurrentConsoleFont(HANDLE, BOOL, PCONSOLE_FONT_INFO );
COORD WINAPI GetConsoleFontSize( HANDLE, DWORD );
GetConsoleFontSize was also missing.