Third party library behaves differently in unreal

I added python as 3rd party library in unreal engine and make it call a python file. If finds the file and the function but returns no result. I then tried a separate project in visual studio to include the same library and call the python and it worked perfect.

The python file takes a few seconds to run and gives a return, can this be the issue?

Hmmm check logs, i know if something external crashes UE4 freeze and later it resumes and drop stack damp in to logs.

There should not be diffrence in library behavior, they can’t magicly change there code, so issue is somewhere in UE4 or your code

I got a way to log the error, it says “[Errno 9] Bad file descriptor” for python. But it did work in another visual studio project so I suspect that there may be some sort of conflicts between UE4 and the library I’m trying to include in.

You build pythion using UBT maybe?

But is it build by UBT, or you build it sepretly?

Yes I loaded the python in build.cs and then include/call it in an actor class function

The python part is just a .py file which got built in runtime I think

I used the python to c api which can be found : 5. Embedding Python in Another Application — Python 2.7.18 documentation
which I believe will call the python file and function and return the result at runtime

Also I noted that simple return like “12345” will work but some python library seems to have conflict with UE4

huh? how do yoiu run that py file then?

I linked its static library and header file with the project and it doesn’t have other external library

That embed lib has any for of external library or it building in to your code?

Ok maybe there some build configurastion problem, or some type incompatibility. Can you also paste your code?

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

    if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32))
    {
        isLibrarySupported = true;
       
        string LibrariesPath = Path.Combine(ThirdPartyPath, "Python27", "libs");
        PublicAdditionalLibraries.Add(Path.Combine(LibrariesPath, "python27.lib"));
    }

    if (isLibrarySupported)
    {
        // Include path
        PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "Python27", "include"));
    }

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

    return isLibrarySupported;
}

public WeMeshOfficial(TargetInfo Target)
{
	PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "Sockets", "Networking","OpenSSL" });
    
    LoadPython27(Target);
	// Uncomment if you are using Slate UI
	// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
	
	// Uncomment if you are using online features
	// PrivateDependencyModuleNames.Add("OnlineSubsystem");
	// if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
	// {
	//		if (UEBuildConfiguration.bCompileSteamOSS == true)
	//		{
	//			DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam");
	//		}
	// }
}

And this is the function where I included it:

FString AyoutubeLinkScrapper::ScrapeLink(FString linkUrl) {

	string i;
	Py_Initialize();
	char * a = Py_GetPath();
	FString Fs = FString(ANSI_TO_TCHAR(a));
	UE_LOG(LogTemp, Warning, TEXT("The default search dependecy is %s"), *Fs);

	PyObject *sys_path = PySys_GetObject("path");
	PyList_Append(sys_path, PyString_FromString("C:/Users/Mik/Documents/GitHub/youtube-dl"));			//Need to change to a relative directory inside the project

	PyObject * pythonFile = PyImport_ImportModule("wemesh_vr_scrapper");

	if (!pythonFile) {
		UE_LOG(LogTemp, Warning, TEXT("Failed to import module"));
	}


	if (pythonFile != NULL) {
		UE_LOG(LogTemp, Warning, TEXT("Found the python file"));

		PyObject * pDict = PyModule_GetDict(pythonFile);
		if (pDict == NULL) {
			UE_LOG(LogTemp, Warning, TEXT("Failed to get a dictionary from the module"));
		}

		PyObject * pythonFunction = PyDict_GetItemString(pDict, (char*)"scrapeLink");
		if (pythonFunction == NULL) {
			UE_LOG(LogTemp, Warning, TEXT("No function was found"));
		}

	
		if (PyCallable_Check(pythonFunction)) {
			UE_LOG(LogTemp, Warning, TEXT("Found the python function, starts calling"));
			PyObject * pValue = Py_BuildValue("(s)", (char*)"https://www.youtube.com/watch?v=pXRviuL6vMY");
			PyObject * presult = PyObject_CallObject(pythonFunction, pValue);
			PyErr_Print();
			if (presult != NULL) {
				UE_LOG(LogTemp, Warning, TEXT("Result is not empty"));
				if (PyList_Check(presult) == true) {
					UE_LOG(LogTemp, Warning, TEXT("Result is a list"));
				}
				if (PyString_Check(presult) == true) {
					UE_LOG(LogTemp, Warning, TEXT("Result is a string"));
					i = PyString_AsString(presult);
				}
				if (PyInt_Check(presult) == true) {
					UE_LOG(LogTemp, Warning, TEXT("Result is an integer"));
				}
				if (PyDict_Check(presult) == true) {
					UE_LOG(LogTemp, Warning, TEXT("Result is a dictionary"));
				}
				if (PyFloat_Check(presult) == true) {
					UE_LOG(LogTemp, Warning, TEXT("Result is a float"));
				}
				if (PyTuple_Check(presult) == true) {
					UE_LOG(LogTemp, Warning, TEXT("Result is a tuple"));
				}
				if (PyFunction_Check(presult) == true) {
					UE_LOG(LogTemp, Warning, TEXT("Result is a function"));
				}
			}
			else {
				UE_LOG(LogTemp, Warning, TEXT("No result is returned"));
				i = "Error!";
			}
		}
	
	}

	Py_Finalize();
	FString returnResult(i.c_str());
	UE_LOG(LogTemp, Warning, TEXT("The final return result is %s"),*returnResult);


	return returnResult;
}

I put it at the buttom, but it’s relatively difficult to see as it imports a relatively large python library

Which part give you Bad File Descriptor?

I solved the problem. It seems like as soon as the python script tries to print out anything from standard output/error it will crush the result. I’m guessing that output from another program running in unreal has some issues?

I solved it by redirecting the output/log to another file.

hi FrankKappa
I think I have the same problem as yours though I am using matlab instead. your solution sounds correct though I don’t understand it correctly. can you elaborate it more please or give me some resources and/or tutorials.

I have a program using matlab that takes file path of an image and return classification result. I want to use it in unreal engine while the player presses a key from keyboard. I tried blueprint functionalities and used FPlatformProcess::CreateProc. It tries to open it but it stops saying “too many inputs”.
I think the problem is input/output handling

hi FrankKappa
I think I have the same problem as yours though I am using matlab instead. your solution sounds correct though I don’t understand it correctly. can you elaborate it more please or give me some resources and/or tutorials.

I have a program using matlab that takes file path of an image and return classification result. I want to use it in unreal engine while the player presses a key from keyboard. I tried blueprint functionalities and used FPlatformProcess::CreateProc. It tries to open it but it stops saying “too many inputs”.
I think the problem is input/output handling