Download

[Plugin] Creating plugin based on third party C++ library. Hit a road block

Hi,

I am currently working on a plugin for UE4 and I have hit a bit of a road block. Everything appears to be setup correctly for loading a external library and using dll’s but I cant seem to get it to compile once I have added a function to my third party component. Any and all help would be appreciated. Basing my plugin off ASP.NET’s SignalR C++ client (https://github.com/aspnet/SignalR-Client-Cpp). Log and some code refs are here. Thank you.

Link to source
https://drive.google.com/file/d/0B56iW1OqxRqBR2NxVEVPalJvSm8/view?usp=sharing

Capture.PNG

hub_connection.h



// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

#pragma once

#include "_exports.h"
#include <memory>
#include <functional>
#include "pplxtasks.h"
#include "json.h"
#include "connection_state.h"
#include "trace_level.h"
#include "log_writer.h"
#include "hub_proxy.h"

namespace signalr
{
    class hub_connection_impl;

    class hub_connection
    {
    public:
		SIGNALR_API explicit hub_connection(const utility::string_t& url, const utility::string_t& query_string = U(""),
            trace_level trace_level = trace_level::all, std::shared_ptr<log_writer> log_writer = nullptr, bool use_default_url = true);

		SIGNALR_API ~hub_connection();

        hub_connection(const hub_connection&) = delete;

        hub_connection& operator=(const hub_connection&) = delete;

		SIGNALR_API pplx::task<void> __cdecl start();
		SIGNALR_API pplx::task<void> __cdecl stop();

		SIGNALR_API hub_proxy __cdecl create_hub_proxy(const utility::string_t& hub_name);

		SIGNALR_API connection_state __cdecl get_connection_state() const;

		SIGNALR_API void __cdecl set_reconnecting(const std::function<void __cdecl()>& reconnecting_callback);
		SIGNALR_API void __cdecl set_reconnected(const std::function<void __cdecl()>& reconnected_callback);
		SIGNALR_API void __cdecl set_disconnected(const std::function<void __cdecl()>& disconnected_callback);

		SIGNALR_API void __cdecl set_headers(const std::unordered_map<utility::string_t, utility::string_t>& headers);

    private:
        std::shared_ptr<hub_connection_impl> m_pImpl;
        pplx::task<web::json::value> invoke_json(const utility::string_t& hub_name, const utility::string_t& method_name, const web::json::value& arguments,
            const std::function<void(const web::json::value&)>& on_progress);
    };
}


SignalRClientComponent.h



// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Components/ActorComponent.h"
#include "hub_connection.h"
#include "SignalRClientComponent.generated.h"


UCLASS( ClassGroup=("Networking"), meta=(BlueprintSpawnableComponent) )
class SIGNALRCLIENT_API USignalRClientComponent : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	USignalRClientComponent();

	// Called when the game starts
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;
 

	UFUNCTION(BlueprintCallable, Category = "SignalR Functions")
		void Connect();
		//void Connect(const FString& InAddressAndPort);
};



SignalRClient.Build.cs



// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

using System.IO;

namespace UnrealBuildTool.Rules
{
	public class SignalRClient : ModuleRules
	{
		private string ThirdPartyPath
	        {
	            get { return Path.GetFullPath(Path.Combine(ModuleDirectory, "../../ThirdParty/")); }
	        }
	    private string SignalRClientThirdParty
	        {
	            get { return Path.GetFullPath(Path.Combine(ThirdPartyPath, "SignalRCppClient")); }
	        }

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

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

                string PlatformString = (Target.Platform == UnrealTargetPlatform.Win64) ? "Win64" : "Win32";
                string SignalRLibPath = Path.Combine(SignalRClientThirdParty, "Libraries");

                PublicAdditionalLibraries.Add(Path.Combine(SignalRLibPath, PlatformString, "signalrclient.lib"));
                
            }
            return isLibrarySupported;
	    }

		public SignalRClient(TargetInfo Target)
		{

            UEBuildConfiguration.bForceEnableExceptions = true;
            PublicIncludePaths.AddRange(
				new string] {
					"SignalRClient/Public",
					Path.Combine(SignalRClientThirdParty, "Includes")
					// ... add public include paths required here ...
				}
				);

			PrivateIncludePaths.AddRange(
				new string] {
					"SignalRClient/Private",
					// ... add other private include paths required here ...
				}
				);

			PublicDependencyModuleNames.AddRange(
				new string]
				{
					"Core",
					"Json",
					"JsonUtilities",
                    "SignalRClient"
					// ... add other public dependencies that you statically link with here ...
				}
				);

			PrivateDependencyModuleNames.AddRange(
				new string]
				{
					"CoreUObject",
					"Engine",
					"Slate",
					"SlateCore",
                    "SignalRClient"
					// ... add private dependencies that you statically link with here ...
				}
				);

			DynamicallyLoadedModuleNames.AddRange(
				new string]
				{
					// ... add any modules that your module loads dynamically here ...
				}
				);

			LoadLib(Target);
		}
	}
}


SignalRClient.h



// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#include "SignalRClientPrivatePCH.h"


class SIGNALRCLIENT_API FSignalRClient : public ISignalRClient
{


	/** IModuleInterface implementation*/
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;
};

void FSignalRClient::StartupModule()
{
	// This code will execute after your module is loaded into memory (but after global variables are initialized, of course.)
}


void FSignalRClient::ShutdownModule()
{
	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
	// we call this function before unloading the module.
}


IMPLEMENT_MODULE(FSignalRClient, SignalRClient)




@ZhymonNorman did you ever get this working? I am currently attempting to import the signalr plugin built from the same github, but as usual the entire third party plugin area is convoluted and difficult to use, can’t get any namespaces to be recognised or the methods to appear.