GetDllExports returns null

Hello, I ultimately want to get Lua working in UE4 for end-user scripting purposes. To this end I have followed the wiki tutorial on linking DLLs as a first/intermediate step. I can nearly complete the tutorial, but fail to actually get the DLL function.

I created a win64 release DLL called “KarmasDLLs.dll”, with symbol exporting. In it is this function:

KARMASDLLS_API float getCircleArea(float radius)
{
	return (float)3.1415926535 * (radius*radius);
}

I compiled this DLL and placed it in my UnrealProjectDirectory/Plugins/KarmasDLLs/ folder. My project is a modification of the C++ quick start guide’s project. I added a ULibraries class as the tutorial instructs. Actually, the tutorial was slightly ambiguous & I am a noob, and so I created ULibraries.cpp & ULibraries.h instead of Libraries.cpp & Libraries.h. Consequently, my relevant class is UULibraries. I will fix this once I understand how to grab/use the DLL function.

My ULibraries.h is:

#pragma once
#include "GameFramework/Actor.h"
#include "ULibraries.generated.h"

UCLASS()
class UULibraries : public UBlueprintFunctionLibrary
{
	GENERATED_UCLASS_BODY()
		UFUNCTION(BlueprintCallable, Category = "Karma Libraries")
		static float getCircleAreaDLL(float radius);
};

While the ULibraries.cpp is:

#include "BasicClass.h"
#include "ULibraries.h"

typedef float(*_getCircleArea)(float radius); //our typedef is must be the same type of our dll function.

UULibraries::UULibraries(const class FPostConstructInitializeProperties& PCIP) : Super(PCIP)
{
}

float UULibraries::getCircleAreaDLL(float radius)
{
	FString filePath = FPaths::Combine( *FPaths::GamePluginsDir(), TEXT("KarmasDLLs/"), TEXT("KarmasDLLs.dll")); // get the plugin path, add the folder to contain the dll, and add the dll name
	if (FPaths::FileExists(filePath))
	{
		void *DLLHandle;
		DLLHandle = FPlatformProcess::GetDllHandle(*filePath); // get dll
		if (DLLHandle != NULL)
		{
			_getCircleArea DLLgetCircleArea = NULL; // the container for our dll function
			FString procName = "getCircleArea"; // the exact name of our dll function to recover
			DLLgetCircleArea = (_getCircleArea)FPlatformProcess::GetDllExport(DLLHandle, *procName); // get the dll function need
			if (DLLgetCircleArea != NULL)
			{
				float out = DLLgetCircleArea(radius); // call our dll function
				return out; // return to UE
			} else {
				return -3.00f;
			}
		} else {
			return -2.00f;
		}
	}
	return -1.00f;
}

When I play the game -3 is printed to the screen (I elsewhere call this function and print the result to screen, of course). This indicates that the following function call returns NULL:

(_getCircleArea)FPlatformProcess::GetDllExport(DLLHandle, *procName);

What have I done wrong? What can I do to fix this? Are there any other resources on how to work with DLLs than that lone tutorial and a scant few scattered Unreal Answers posts? As far as I can tell all of the arguments I am supplying to that function are correct.

Thank you!

I’m having the same problem…

I’m having the same problem… ¿Any solution?

Need help!!!

the following function call returns NULL:

(_getCircleArea)FPlatformProcess::GetDllExport(DLLHandle, *procName);

in dll code I put:

__declspec(dllexport) float getCircleArea(float radius)
{
return 3.1416 * (radius*radius);
}

The solution is create a .def in dll project:

LIBRARY “MyDLL”
EXPORTS
getCircleArea

If it returns NULL means that it couldn’t find the function.

  • Funcion names are “mangled”. There’s plenty of information about it on the net. To fix this surround your .h and .cpp code with extern “C” {…}. This will tell the compiler to use C instead of C++ naming on the dll.
  • Function is not exactly the same. Same parameters and same return value.

One important note about the return value: if the return value is a pointer, for instance. A pointer to a particular internal type… you can’t say in your code that it’s a “void*”, which is the most generic way to tell it it’s a pointer.
GetDllExport will not know if the type is void* or not. It has to be the exact same type.

In case you don’t want to expose what that type is, you will have to use an Opaque Type.

Opaque types hide the implementation of this particular type so that the client / user of the dll will not be able to create copies, run a sizeof, and many other things that you maybe want to avoid.

To use opaque types, the easiest way, is to perform casting when returning this pointer or when you receive this pointer in every function of the dll. The casting will be to a new type you will create.
Creating that type is just doing a typedef:

typedef YourType* NewTypeNameHandler;

This is what windows functions do, for example. They return XXXXXSOMENAME_HANDLER so that you know what that is. Otherwise it would use void* everywhere.

The reason for not using void* and using a new name is that, for the user of the DLL, the type will not be a generic one, but one with a particular name that they will know how to use. If it’s just moving around pointers, using a new name will allow them to find the corresponding pointer they need for each function if you have to use that pointer in another function’s arguments.

I suggest you read more about it.

No. That doesn’t work. Using a .def is the same as adding declspec … dllexport