// A program to use a run-time loaded DLL.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>

#include <iostream>

using namespace std;

//Creates a new type of variable which is a function pounter called, cryptFunPointer.
typedef void (*cryptFunPointer) (int key , char inString, char outString, int length);


int _tmain(int argc, _TCHAR* argv[])
{
    HINSTANCE hinstLib; 

    const int SIZE = 20;
    char theString [SIZE]; // entered by the user
    char theEncryptedString [SIZE]; // after encryption
    char theDecryptedString [SIZE]; // after decryption – should be the same as theString

    cryptFunPointer encryptFunPointer, decryptFunPointer;//Declares two variables of the type cryptFunPointer

    cout << "Enter a string: ";
    cin.getline(theString,SIZE);

    // Get a handle to the DLL module.
    hinstLib = LoadLibrary(TEXT("dynamicLib.DLL"));

    // If the handle is valid, try to get the function address.
    if (hinstLib != NULL){

        encryptFunPointer = (cryptFunPointer) GetProcAddress(hinstLib, "encrypt");

        decryptFunPointer = (cryptFunPointer) GetProcAddress(hinstLib, "decrypt");
    }
    else{
        cout<<"Error DLL not found" <<endl;
    }

    // If the function address is valid, call the function.
    if (encryptFunPointer != NULL){
    (encryptFunPointer) (3, theString[SIZE], theEncryptedString[SIZE], SIZE);
    //  cout << endl << "Encrypted: " << theEncryptedString;
    }
    else{
        cout<<"Error NULL pointer"<<endl;   
    }

    system ("PAUSE");

    return 0;
}

The program compiles and runs just fine but i get the Error NULL pointer out put on the screen.

It's basically a program that takes a string passes it to a run time loaded dll that then carrys out a very basic encryption.

I think GetProcAddress for encryptFunPointer isn't finding the encrypt functions address in the DLL. This is probably to do with how I define the typedef as it's supposed to take two char arrays as an argument.

Thanks for any help in advance.

Dani AI

Generated

A few concrete things to try — the code you posted has three separate, fixable issues that explain why GetProcAddress returns NULL and why the call you make would be wrong even if you did get a pointer.

The immediate fixes (what to change now)

  • The parameter types must be pointer types, not char. Change the typedef to accept char* (or const char* for input).
  • When calling the function pass the array name (which decays to a pointer), not theString[SIZE] (that indexes one char and is out-of-bounds).
    Example corrected snippets:
typedef void (__cdecl *cryptFunPointer)(int key, const char *inString, char *outString, int length);

encryptFunPointer = (cryptFunPointer)GetProcAddress(hinstLib, "encrypt");
if (encryptFunPointer)
    encryptFunPointer(3, theString, theEncryptedString, SIZE);

Why GetProcAddress returned NULL (and what was hinting at)

  • GetProcAddress returns NULL when the named symbol isn't exported exactly as requested; check GetLastError for ERROR_PROC_NOT_FOUND for confirmation. (learn.microsoft.com)
  • C++ functions get name-mangled and calling conventions change the exported name; if the DLL exported a C++-decorated or stdcall-decorated name, "encrypt" won't match. Use extern "C" or a .def file / explicit export to get an undecorated name. (learn.microsoft.com)

How to export and match the signature

  • In the DLL, export an unmangled symbol and pick a calling convention you own. Example:
extern "C" __declspec(dllexport) void __cdecl encrypt(int key, const char *inString, char *outString, int length);

See the Microsoft docs on creating/exporting DLL functions for recommended patterns. (learn.microsoft.com)

Quick troubleshooting checklist

  • Inspect exports (dumpbin /exports dynamicLib.dll or Dependency Walker) to see the exact exported names.
  • Verify the calling convention used when building the DLL (cdecl vs stdcall) and make the function-pointer typedef match. (learn.microsoft.com)
  • Check GetLastError immediately after GetProcAddress for the specific failure. With those three fixes you should get a non-NULL pointer and be safe to call the function.

Recommended Answers

All 3 Replies

The problem has nothing to do with the typedef or type of your function pointer. The type of the pointer returned by GetProcAddress is void*, and then you cast it to what it is supposed to be. In other words, the information about what kind of function is in the DLL is lost, and thus, there is no way to verify it. It is entirely your responsibility to make sure that the function-pointer type to which you cast it is exactly the same as the function exported by the DLL (parameters and return type must match). If you get it wrong, you will get a crash (or other corruption of some kind), not a NULL pointer.

If you are getting a NULL pointer out of the GetProcAddress call, it means that functions with that name could not be found in the DLL.

You can use a utility like or dependency walker to inspect the list of exported symbols from the DLL. Also, of course, I don't need to remind you that the DLL functions must be declared with extern "C", see explanation.

Thanks for the response, sorry for lack of understanding this is the first time I've attempted to write a run time DLL.
The compiler isn't throwing the NULL pointer error. It's hitting the 'else' statement in the second 'for loop' and out putting the cout statement.

I've doubled checked the DLL and the functions are exactly the same. It's declared to return void because the function doesn't return any thing.

The only difference is the char inString and char outString aren't declared as arrays when declaring the type def but the complier doesn't like me doing this.

Please show the DLL's code (or at least, the function declarations).

The compiler isn't throwing the NULL pointer error. It's hitting the 'else' statement in the second 'for loop' and out putting the cout statement.

Yes, that is exactly what I understood.

I've doubled checked the DLL and the functions are exactly the same. It's declared to return void because the function doesn't return any thing.

So, you have checked the list of exported symbols from the DLL. I am not talking about the source code of the DLL or its function declarations, but the actual list of symbols that you could be able to get out of the DLL file itself.

The only difference is the char inString and char outString aren't declared as arrays when declaring the type def but the complier doesn't like me doing this.

There is a big difference between an array of chars and a char. You cannot use one for the other, this will result in a stack corruption or crash if you try to call the function (assuming it is not NULL).

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.