Unresolved external symbol for custom third party plugin (integrating Vosk)

I’m currently trying to integrate Vosk - Offline Speech Recognition - into UE4. They only provide 4 dll files from their website:

libgcc_s_seh-1.dll
libstdc++-6.dll
libwinpthread.dll
vosk.dll

Following online sources I was able to create a third party plugin with the dll, header, etc. all present. Here is my Build.cs file for the ThirdParty Module:

public VoskLibrary(ReadOnlyTargetRules Target) : base(Target)
	{
		Type = ModuleType.External;

		var winPath =
			Path.GetFullPath(Path.Combine(PluginDirectory, "Source", "ThirdParty", "VoskLibrary", "Win64"));

		PublicIncludePaths.Add(Path.GetFullPath(Path.Combine(PluginDirectory, "Source", "ThirdParty", "VoskLibrary",
			"Win64/include")));
		PublicAdditionalLibraries.Add(Path.Combine(winPath, "lib", "vosk.lib"));
		PublicDelayLoadDLLs.Add("vosk.dll");

		// Bring into the binaries folder as we need to load vosk.dll with access to the top 3 dlls.
		CopyToBinaries(Path.Combine(winPath, "bin", "libgcc_s_seh-1.dll"), Target);
		CopyToBinaries(Path.Combine(winPath, "bin", "libstdc++-6.dll"), Target);
		CopyToBinaries(Path.Combine(winPath, "bin", "libwinpthread-1.dll"), Target);
		CopyToBinaries(Path.Combine(winPath, "bin", "vosk.dll"), Target);
	}

And here is the module that loads the dll build.cs file:

public Vosk(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;

		PublicDependencyModuleNames.AddRange(
			new string[]
			{
				"Core",
				"VoskLibrary"
			}
		);

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

Finally, I’ll provide the module’s startup logic that loads the dll:

void FVoskModule::StartupModule()
{
	// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module

	// Get the base directory of this plugin
	FString BaseDir = FPaths::ConvertRelativePathToFull(IPluginManager::Get().FindPlugin("Vosk")->GetBaseDir());

	// Add on the relative location of the third party dll and load it
	FString LibraryPath = FPaths::Combine(*BaseDir, TEXT("Source/ThirdParty/VoskLibrary/Win64/bin/vosk.dll"));

	VoskLibraryHandle = !LibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*LibraryPath) : nullptr;

	if (VoskLibraryHandle)
	{
		// Call the test function in the third party library that opens a message box
		UE_LOG(LogTemp, Warning, TEXT("Vosk Library successfully loaded!"));
	}
	else
	{
		FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("ThirdPartyLibraryError", "Failed to load example third party library!"));
	}
}

For clarity in the bug discussion, here is a quick view of vosk_api.h:

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

typedef struct VoskModel;

VoskModel *vosk_model_new(const char *model_path);

#ifdef __cplusplus
}
#endif

Up until this point, everything loads and compiles. However, the issue arises when I try to use any function from the vosk_api.h file inside my game module. Importing this file works fine, even referencing the structs does not produce a “unresolved external symbol” error. However, once I reference any function call, it starts producing the error. Some notes was that the lib file was generated both by hand using VS command prompt as well as dll2lib. In both instances, no discernable change could be identified. I have used these exact dll files in Java and had the library work. I think I’m just lost about possible issues and have really tried to look through others work and read online (github repos such as libmongo, boost, etc. imported into UE4). Any help is much appreciated!

Hi all again,

The error was due to libvosk.dll not providing their own .lib file. After reading this stackoverflow question, I tried iterating over the machine and name of the dll. This is a twofold problem, A) Make sure the lib file was generated with the proper machine. B) Make sure you DO NOT change the dll names. Hope this helps others down the road.