要實現UE4C++到第三方庫的調用,需要自己在自己創建的插件庫里的\Source路徑下創建一個目錄為ThirdParty的文件夾在里面放入你需要放入的第三方庫
當你放入了第三方庫的文件之后,需要自己寫一個cs文件,用於UE4自己添加lib和include
然后需要在cs填寫庫的運用

using UnrealBuildTool; public class PythonThirdParty : ModuleRules { public PythonThirdParty(ReadOnlyTargetRules Target) : base(Target) { //python版本 //string PythonThirdPartyValue = "2.7"; //表示第三方庫 Type= ModuleType.External; //第三方庫新模塊根目錄目錄路徑 //string RootPath = Target.UEThirdPartySourceDirectory + "PythonThirdParty/"; //包含的頭文件路徑,因為編譯的庫里面都是鏈接過的編譯單元,可以認為編譯單元是不包含頭文件的,所以在之后的使用時還需要獲取到頭文件的聲明信息 PublicIncludePaths.Add(ModuleDirectory + "/include/"); if(Target.Platform == UnrealTargetPlatform.Win32 || Target.Platform == UnrealTargetPlatform.Win64) { //第三方靜態庫的路徑 PublicLibraryPaths.Add(ModuleDirectory + "/libs/"); //第三方靜態庫的名稱 PublicAdditionalLibraries.Add("python27.lib"); PublicAdditionalLibraries.Add("_bsddb.lib"); PublicAdditionalLibraries.Add("_ctypes.lib"); PublicAdditionalLibraries.Add("_elementtree.lib"); PublicAdditionalLibraries.Add("_hashlib.lib"); PublicAdditionalLibraries.Add("_msi.lib"); PublicAdditionalLibraries.Add("_multiprocessing.lib"); PublicAdditionalLibraries.Add("_socket.lib"); PublicAdditionalLibraries.Add("_sqlite3.lib"); PublicAdditionalLibraries.Add("_ssl.lib"); PublicAdditionalLibraries.Add("_testcapi.lib"); PublicAdditionalLibraries.Add("_tkinter.lib"); PublicAdditionalLibraries.Add("bz2.lib"); PublicAdditionalLibraries.Add("pyexpat.lib"); PublicAdditionalLibraries.Add("select.lib"); PublicAdditionalLibraries.Add("unicodedata.lib"); PublicAdditionalLibraries.Add("winsound.lib"); } } }
這樣我們就能在UE4插件的cs文件里面添加自身命名的第三方庫名稱(cs文件的命名)
現在我們就可以使用python這個第三方庫了,現在我們需要使用C++來調用python,首先我們需要把python文件的東西整理成一個函數

import requests import os def OutBaiduAPILngAndLat(url,ak,path,origin,destination): #url = 'http://api.map.baidu.com/direction/v2/riding?' params = { 'ak':ak, 'origin':origin, 'destination':destination } r = requests.get(url,params) r_js = r.json() routes_ = r_js['result']['routes'][0] dis_ = routes_['distance'] time_ = routes_['duration'] f_path = path f_re = open(f_path,'w') with open(f_path,'r+') as f: read_data = f.read() f.seek(0) f.truncate() f.write(read_data.replace('apple','android')) steps_ = routes_['steps'] f_re.writelines(['Start','\n']) for step in steps_: path_ = step['path'] point_lst = path_.split(';') f_re.writelines(['------','\n']) for point in point_lst: lng = point.split(',')[0] lat = point.split(',')[1] f_re.writelines([str(lng),',',str(lat),'\n']) f_re.writelines(['End','\n']) f_re.writelines(['time:',str(time_),'\n']) f_re.writelines(['distance:',str(dis_),'\n']) f_re.close()
我設置的函數名為OutBaiduAPILngAndLat,需要C++傳入的參數有五個,所以我們需要在C++里定義五個參數,方法為:

// 方法一:設置參數 或使用 /* PyObject* args = PyTuple_New(2); // 2個參數 PyObject* arg1 = PyUnicodeUCS2_FromString(Origin); // 參數一 PyObject* arg2 = PyUnicodeUCS2_FromString(Destination); // 參數二 PyTuple_SetItem(args, 0, arg1); PyTuple_SetItem(args, 1, arg2); */ // 方法二 PyObject* args = Py_BuildValue("(sssss)", API, s.c_str(), textPath.c_str(), Origin, Destination); // 調用函數 PyObject* pRet = PyObject_CallObject(pv, args);
完整代碼:

// 調用Python Py_Initialize(); // FPaths::ProjectPluginsDir():獲取UE4插件文件夾的路徑 // Path:自身python文件目錄位置 std::string chdir_cmd = std::string("sys.path.append(\"") + TCHAR_TO_UTF8(*FPaths::ProjectPluginsDir()) + Path + "\")"; const char* cstr_cmd = chdir_cmd.c_str(); PyRun_SimpleString("import sys"); //python定義到自身寫的python文件目錄 PyRun_SimpleString(cstr_cmd); // 加載自己python文件 PyObject* moduleName = PyString_FromString(Type); PyObject* pModule = PyImport_Import(moduleName); if (!pModule) // 加載模塊失敗 { UE_LOG(LogTemp, Warning, TEXT("[ERROR] Python get module failed.")); return; } // 加載函數 PyObject* pv = PyObject_GetAttrString(pModule, "OutBaiduAPILngAndLat"); if (!pv || !PyCallable_Check(pv)) // 驗證是否加載成功 { UE_LOG(LogTemp, Warning, TEXT("[ERROR] Can't find funftion (OutBaiduAPILngAndLat)")); return ; } // 插件目錄絕對位置 FString UE4Path = FPaths::ConvertRelativePathToFull(FPaths::ProjectPluginsDir()); FString UE4TextPath; TArray<TCHAR> UE4PathArray = UE4Path.GetCharArray(); for (auto & Item : UE4PathArray) { FString A; if (FString(1,&Item).Equals("/")) { A = "\\"; } else { A = FString(1, &Item); } UE4TextPath += A; } std::string textPath = TCHAR_TO_UTF8(*UE4TextPath) + std::string("PythonPlugins\\Source\\ThirdParty\\PythonThirdParty\\Resources\\walking.txt"); std::string file = TCHAR_TO_UTF8(*FPaths::ProjectPluginsDir()) + std::string("PythonPlugins/Source/ThirdParty/PythonThirdParty/Resources/MyBaiDuAk.txt"); std::ifstream infile; infile.open(file.data()); //將文件流對象與文件連接起來 std::string s; getline(infile, s); // 方法一:設置參數 或使用 /* PyObject* args = PyTuple_New(2); // 2個參數 PyObject* arg1 = PyUnicodeUCS2_FromString(Origin); // 參數一 PyObject* arg2 = PyUnicodeUCS2_FromString(Destination); // 參數二 PyTuple_SetItem(args, 0, arg1); PyTuple_SetItem(args, 1, arg2); */ // 方法二 PyObject* args = Py_BuildValue("(sssss)", API, s.c_str(), textPath.c_str(), Origin, Destination); // 調用函數 PyObject* pRet = PyObject_CallObject(pv, args); Py_Finalize(); //釋放資源
如果需要看項目完整代碼可以查看github:https://github.com/Monocluar/UE4RealRoadPlanning