LNK2019 errors, using MongoDB lib

Hey!

I have been trying to add MongoDB libraries to my project. I followed the tutorial here. It compiles fine untill I start using the hpp files, creating instances of classes. Then I get the following output:

CompilerResultsLog: Info [3/3] Link UE4Editor-MongoDBTest-4863.dll

CompilerResultsLog: Info Creating library F:\Skole\UnrealTest\MongoDBTest\Intermediate\Build\Win64\UE4Editor\Development\UE4Editor-MongoDBTest-4863.lib and object F:\Skole\UnrealTest\MongoDBTest\Intermediate\Build\Win64\UE4Editor\Development\UE4Editor-MongoDBTest-4863.exp

CompilerResultsLog:Error: Error MongoDBConnectTest.cpp.obj : error LNK2019: unresolved external symbol “__declspec(dllimport) public: __cdecl mongocxx::v_noabi::instance::instance(void)” (_imp??0instance@v_noabi@mongocxx@@QEAA@XZ) referenced in function “public: virtual void __cdecl AMongoDBConnectTest::BeginPlay(void)” (?BeginPlay@AMongoDBConnectTest@@UEA AXXZ)

CompilerResultsLog:Error: Error MongoDBConnectTest.cpp.obj : error LNK2019: unresolved external symbol “__declspec(dllimport) public: __cdecl mongocxx::v_noabi::instance::~instance(void)” (_imp??1instance@v_noabi@mongocxx@@QEAA@XZ) referenced in function “public: virtual void __cdecl AMongoDBConnectTest::BeginPlay(void)” (?BeginPlay@AMongoDBConnectTest@@UE AAXXZ)

CompilerResultsLog:Error: Error F:\Skole\UnrealTest\MongoDBTest\Binaries\Win64\UE4Editor-MongoDBTest-4863.dll : fatal error LNK1120: 2 unresolved externals

CompilerResultsLog: Info ERROR: UBT ERROR: Failed to produce item: F:\Skole\UnrealTest\MongoDBTest\Binaries\Win64\UE4Editor-MongoDBTest-4863.dll

Anyone know what is going on? I have tried googling it and trying different things that seem to have worked for others.

The build.cs file:

using UnrealBuildTool;
using System.IO;

public class MongoDBTest : ModuleRules
{
    private string ModulePath {
        get { return ModuleDirectory; }
    }

    private string ThirdPartyPath {
        get { return Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/")); }
    }

    public MongoDBTest(TargetInfo Target)
	{
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });

		PrivateDependencyModuleNames.AddRange(new string[] {  });

        LoadMongoDB(Target);

	}

    public bool LoadMongoDB(TargetInfo Target) {
        bool isLibrarySupported = false;

        if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32)) {
            isLibrarySupported = true;

            string LibrariesPath = Path.Combine(ThirdPartyPath, "MongoDB", "Libraries");
//            PublicAdditionalLibraries.Add(Path.Combine(LibrariesPath, "libbsoncxx." + "lib"));
            PublicAdditionalLibraries.Add(Path.Combine(LibrariesPath, "libmongocxx." + "lib"));
        }

        if (isLibrarySupported) {
            PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "MongoDB", "Includes"));
        }

        Definitions.Add(string.Format("WITH_MONGODB_BINDING={0}", isLibrarySupported ? 1 : 0));

        return isLibrarySupported;
    }
}

The header file of the class I use for testing:

#pragma once

#include "GameFramework/Actor.h"
#include "MongoDBConnectTest.generated.h"

UCLASS()
class MONGODBTEST_API AMongoDBConnectTest : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AMongoDBConnectTest();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	UFUNCTION()
	void testConnection();
};

Here is the cpp file of the class:

#include "MongoDBTest.h"
#include "MongoDBConnectTest.h"
#include "mongocxx/instance.hpp"

// Sets default values
AMongoDBConnectTest::AMongoDBConnectTest()
{
}

void AMongoDBConnectTest::BeginPlay() {
	testConnection();
	Super::BeginPlay();
}

void AMongoDBConnectTest::testConnection() {
	mongocxx::instance inst{};	
}

When creating the library I followed this one and this one. In addition to having certain settings set:

  1. Platform: x64
  2. Runtime Library: Multi-threaded DLL (/MD)
  3. Configuration Type: Static Library (.lib)

I also have boost added in the Includes folder.

Hi Yllam,

The tutorial that you followed only includes and links the .lib files, it didn’t cover dlls. For MongoDB (judging from the error, you need to include the dlls as well). I would have a look at https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Source/ThirdParty/Steamworks/Steamworks.build.cs (particularly the parts regarding RuntimeDependencies.Add(...); as how to copy/add a dll) and https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Plugins/Online/OnlineSubsystemSteam/Source/Private/OnlineSubsystemModuleSteam.cpp (to load the dll at runtime do something as the function void FOnlineSubsystemSteamModule::LoadSteamModules() or have a look in the engine for an example that uses FPlatformProcess::GetDllHandle).

Hope that helps. Cheers,

if you want to connect to a remote mongodb instance, this will break security. you’ll need to add the username/password or the certificate you’ll be using for connection. this will result every single client having your mongodb instance credentials. someone will definitely empty your db… keep db connections on server side, call/connect to a rest api. there are great plugins in marketplace for both socket and http connections.

You don’t have to create a new plugin for it, you can load the dlls in your gamemodule.cpp StartupModule() function if you wish.

So what you are telling me implicitly is that i need to load the dll in runtime as a plugin? Because I am a bit confused for the last part.

Ok, I will try it out and come back to you. Thank you for the possible fix!

I can’t seem to get it to work. There is no change. Here is what I did:

In the header file named the same as the project I added:

class MongoDBTest : public IModuleInterface {
    	virtual void StartupModule() override;
    	virtual void ShutdownModule() override;
    	void* SteamDLLHandle;
};

Then in the .cpp i added:

    void MongoDBTest::StartupModule() {
        		FString RootMongoDBPath = "../../ThirdParty/MongoDB/DLL" ;
        		//FPlatformProcess::PushDllDirectory(*RootMongoDBPath);
        		SteamDLLHandle = FPlatformProcess::GetDllHandle(*(RootMongoDBPath + "mongocxx.dll"));
        		if (SteamDLLHandle == nullptr) {
        			UE_LOG(LogTemp, Warning, TEXT("Failed loading MongoDB dll"));
        		} else {
        			UE_LOG(LogTemp, Warning, TEXT("Loaded MongoDB dll"));
        		}
        }
   
    void MongoDBTest::ShutdownModule() {
    	if (SteamDLLHandle != nullptr) {
    		FPlatformProcess::FreeDllHandle(SteamDLLHandle);
    		SteamDLLHandle = nullptr;
    	}
    }

In the MongoDBTest.Build.cs I added:

 string MongoDBBinPath = Path.Combine(ThirdPartyPath, "MongoDB", "DLL");
                PublicDelayLoadDLLs.Add(MongoDBBinPath + "mongocxx.dll");
                RuntimeDependencies.Add(new RuntimeDependency(MongoDBBinPath + "mongocxx.dll"));

It seems like the StartupModule() is not running at all… as the logs are not displayed.

I believe it needs to be a game module interface;

class FMongoDBTest : public FDefaultGameModuleImpl
{
    ...
}
IMPLEMENT_PRIMARY_GAME_MODULE( FMongoDBTest, MongoDBTest, "MongoDBTest" );

That does nothing sadly. Same errors as before.

It’s ok as long as you keep db communication exclusivly in server code and it actully better then using http