UE4根據真實地圖來生成行走道路(三)


要實現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");

        }
     }
}
.cs

這樣我們就能在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()
.py

我設置的函數名為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);
.cpp

完整代碼:

// 調用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();     //釋放資源
.cpp

如果需要看項目完整代碼可以查看github:https://github.com/Monocluar/UE4RealRoadPlanning


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM