编组公约C++ vs c#/mono

发布于 2025-01-30 13:02:28 字数 5722 浏览 2 评论 0原文

我有以下C ++ API

#ifndef AGUR_H
#define AGUR_H

#define AGUR_EXPORT __attribute__((visibility("default")))

#include <cstdint>

extern "C"
{
    AGUR_EXPORT void sphericalRelativePoseSolveFromFile(
        const char* filePathStatic,
        const char* filePathDynamic,
        const char* solverConfigJson,
        char** solverSolutionJson);

    AGUR_EXPORT void sphericalRelativePoseSolve(
        const char* rawImageStatic,
        const char* rawImageDynamic,
        int imageWidth,
        int imageHeight,
        const char* solverConfigJson,
        char** solverSolutionJson);
}
#endif // AGUR_H

我对上述第一个方法的实现(我关注的方法)是

void sphericalRelativePoseSolveFromFile(
    const char* filePathStatic,
    const char* filePathDynamic,
    const char* solverConfigJson,
    char** solverSolutionJson)
{
    json cj = json::parse(solverConfigJson);
    types::SolverConfiguration solverConfig = cj.get<types::SolverConfiguration>();

    std::string sfp = std::string(filePathStatic);
    std::string dfp = std::string(filePathDynamic);

    agur::sfm::SphericalRelativePoseSolver sphericalRelativePoseSolver(solverConfig);
    types::SolverSolution solverSolution = sphericalRelativePoseSolver.solve(sfp, dfp);

    const json sj{ solverSolution };
    std::string jsonString = sj[0].dump();

    char* tmp = (char*)jsonString.c_str();
    size_t len = std::strlen(tmp) + 1;
    *solverSolutionJson = (char*)malloc(len);
    std::memcpy((void*)*solverSolutionJson, tmp, len);
}

我将C ++的API称为以下内容,结果是我期望和想要的。

std::string ss = "/Alignment/Theta_R0010732_2048.jpg";
const char* staticFilePath = ss.c_str();

std::string ds = "/Alignment/Theta_R0010733_2048.jpg";
const char* dynamicFilePath = ds.c_str();

const char* solverConfigJson =
    "{"
        "\"acRansacMaxThreshold\": 4.0,"
        "\"outputEssentialGeometry\": true,"
        "\"outputFeatures\": true,"
        "\"outputInliers\": true,"
        "\"outputMatches\": false,"
        "\"unstableSolutionInlierThreshold\": 60,"
        "\"useUprightRelativePoseSolver\": true"
    "}";

char solverSolutionJson[] = "";
char* ptrSolverSolutionJson = solverSolutionJson;

sphericalRelativePoseSolveFromFile(staticFilePath, dynamicFilePath, solverConfigJson, &ptrSolverSolutionJson);

std::cout << ptrSolverSolutionJson << std::endl;

这将预期的求解器结果打印为JSOMN-很棒。但是,我现在想从Unity项目中调用API。到目前为止,Unity代码是

using System;
using System.IO;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Networking;

public class AgurIvocation : MonoBehaviour
{
    private string _status = string.Empty; 

    #if UNITY_IOS || UNITY_TVOS
        // On iOS plugins are statically linked into
        // the executable, so we have to use __Internal as the
        // library name.
        private const string Import = "__Internal";
    #else
        // Other platforms load plugins dynamically, so pass the
        private const string Import = "agur";
    #endif

    [DllImport(Import)]
    private static unsafe extern void sphericalRelativePoseSolveFromFile(
        string filePathStatic,
        string filePathDynamic,
        string solverConfigJson,
        out string[] solverSolutionJson);

    [DllImport(Import)]
    private static unsafe extern void sphericalRelativePoseSolve(
        string rawImageStatic,
        string rawImageDynamic,
        int imageWidth,
        int imageHeight,
        string solverConfigJson,
        out string[] solverSolutionJson);

    void Start()
    {
        try
        {
            var filePathStatic = "/Alignment/Theta_R0010732_2048.jpg";
            var filePathDynamic = "/Alignment/Theta_R0010733_2048.jpg";
            var solverConfigJson =
                "{" +
                    "\"acRansacMaxThreshold\": 4.0," +
                    "\"outputEssentialGeometry\": true," +
                    "\"outputFeatures\": true," +
                    "\"outputInliers\": true," +
                    "\"outputMatches\": false," +
                    "\"unstableSolutionInlierThreshold\": 60," +
                    "\"useUprightRelativePoseSolver\": true" +
                "}";


            var solverSolutionJson = new string[] { };
            sphericalRelativePoseSolveFromFile(filePathStatic, filePathDynamic, solverConfigJson, out solverSolutionJson);
            Console.WriteLine(solverSolutionJson[0]);
        }
        catch (Exception e)
        {
            _status = e.ToString();
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private string UnpackAsset(string path)
    {

#if !UNITY_ANDROID
        return Path.Combine(Application.streamingAssetsPath, path);
#endif

        var inputFilePath = Path.Combine(Application.streamingAssetsPath, path);
        var outputFilePath = Path.Combine(Application.persistentDataPath, path);

        var loadingRequest = UnityWebRequest.Get(inputFilePath);
        loadingRequest.SendWebRequest();

        while (!loadingRequest.isDone)
        {
            if (loadingRequest.isNetworkError || loadingRequest.isHttpError)
            {
                break;
            }
        }

        if (!loadingRequest.isNetworkError && !loadingRequest.isHttpError)
        {
            File.WriteAllBytes(outputFilePath, loadingRequest.downloadHandler.data);
            return outputFilePath;
        }

        string errorMessage = $"Unpacking asset failed: {path}, reason: {loadingRequest.error}";
        throw new Exception(errorMessage);
    }
}

solversolutionJSON变量,但我一无所获。简而言之,这是不起作用的 - 有人可以建议您如何从Unity/Mono中完成此操作?

I have the following C++ API

#ifndef AGUR_H
#define AGUR_H

#define AGUR_EXPORT __attribute__((visibility("default")))

#include <cstdint>

extern "C"
{
    AGUR_EXPORT void sphericalRelativePoseSolveFromFile(
        const char* filePathStatic,
        const char* filePathDynamic,
        const char* solverConfigJson,
        char** solverSolutionJson);

    AGUR_EXPORT void sphericalRelativePoseSolve(
        const char* rawImageStatic,
        const char* rawImageDynamic,
        int imageWidth,
        int imageHeight,
        const char* solverConfigJson,
        char** solverSolutionJson);
}
#endif // AGUR_H

My implementation for the first method above (and the one I am concerned with) is

void sphericalRelativePoseSolveFromFile(
    const char* filePathStatic,
    const char* filePathDynamic,
    const char* solverConfigJson,
    char** solverSolutionJson)
{
    json cj = json::parse(solverConfigJson);
    types::SolverConfiguration solverConfig = cj.get<types::SolverConfiguration>();

    std::string sfp = std::string(filePathStatic);
    std::string dfp = std::string(filePathDynamic);

    agur::sfm::SphericalRelativePoseSolver sphericalRelativePoseSolver(solverConfig);
    types::SolverSolution solverSolution = sphericalRelativePoseSolver.solve(sfp, dfp);

    const json sj{ solverSolution };
    std::string jsonString = sj[0].dump();

    char* tmp = (char*)jsonString.c_str();
    size_t len = std::strlen(tmp) + 1;
    *solverSolutionJson = (char*)malloc(len);
    std::memcpy((void*)*solverSolutionJson, tmp, len);
}

I call this API from C++ as followws and the results are what I expect and want.

std::string ss = "/Alignment/Theta_R0010732_2048.jpg";
const char* staticFilePath = ss.c_str();

std::string ds = "/Alignment/Theta_R0010733_2048.jpg";
const char* dynamicFilePath = ds.c_str();

const char* solverConfigJson =
    "{"
        "\"acRansacMaxThreshold\": 4.0,"
        "\"outputEssentialGeometry\": true,"
        "\"outputFeatures\": true,"
        "\"outputInliers\": true,"
        "\"outputMatches\": false,"
        "\"unstableSolutionInlierThreshold\": 60,"
        "\"useUprightRelativePoseSolver\": true"
    "}";

char solverSolutionJson[] = "";
char* ptrSolverSolutionJson = solverSolutionJson;

sphericalRelativePoseSolveFromFile(staticFilePath, dynamicFilePath, solverConfigJson, &ptrSolverSolutionJson);

std::cout << ptrSolverSolutionJson << std::endl;

This prints out the expected solver results as jsomn - great. However, I now want to call the API from a Unity project. The Unity code so far is

using System;
using System.IO;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Networking;

public class AgurIvocation : MonoBehaviour
{
    private string _status = string.Empty; 

    #if UNITY_IOS || UNITY_TVOS
        // On iOS plugins are statically linked into
        // the executable, so we have to use __Internal as the
        // library name.
        private const string Import = "__Internal";
    #else
        // Other platforms load plugins dynamically, so pass the
        private const string Import = "agur";
    #endif

    [DllImport(Import)]
    private static unsafe extern void sphericalRelativePoseSolveFromFile(
        string filePathStatic,
        string filePathDynamic,
        string solverConfigJson,
        out string[] solverSolutionJson);

    [DllImport(Import)]
    private static unsafe extern void sphericalRelativePoseSolve(
        string rawImageStatic,
        string rawImageDynamic,
        int imageWidth,
        int imageHeight,
        string solverConfigJson,
        out string[] solverSolutionJson);

    void Start()
    {
        try
        {
            var filePathStatic = "/Alignment/Theta_R0010732_2048.jpg";
            var filePathDynamic = "/Alignment/Theta_R0010733_2048.jpg";
            var solverConfigJson =
                "{" +
                    "\"acRansacMaxThreshold\": 4.0," +
                    "\"outputEssentialGeometry\": true," +
                    "\"outputFeatures\": true," +
                    "\"outputInliers\": true," +
                    "\"outputMatches\": false," +
                    "\"unstableSolutionInlierThreshold\": 60," +
                    "\"useUprightRelativePoseSolver\": true" +
                "}";


            var solverSolutionJson = new string[] { };
            sphericalRelativePoseSolveFromFile(filePathStatic, filePathDynamic, solverConfigJson, out solverSolutionJson);
            Console.WriteLine(solverSolutionJson[0]);
        }
        catch (Exception e)
        {
            _status = e.ToString();
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private string UnpackAsset(string path)
    {

#if !UNITY_ANDROID
        return Path.Combine(Application.streamingAssetsPath, path);
#endif

        var inputFilePath = Path.Combine(Application.streamingAssetsPath, path);
        var outputFilePath = Path.Combine(Application.persistentDataPath, path);

        var loadingRequest = UnityWebRequest.Get(inputFilePath);
        loadingRequest.SendWebRequest();

        while (!loadingRequest.isDone)
        {
            if (loadingRequest.isNetworkError || loadingRequest.isHttpError)
            {
                break;
            }
        }

        if (!loadingRequest.isNetworkError && !loadingRequest.isHttpError)
        {
            File.WriteAllBytes(outputFilePath, loadingRequest.downloadHandler.data);
            return outputFilePath;
        }

        string errorMessage = 
quot;Unpacking asset failed: {path}, reason: {loadingRequest.error}";
        throw new Exception(errorMessage);
    }
}

But I am getting nothing out of the solverSolutionJson variable. Simply, this is not working - can someone advise are to how this should be done from Unity/Mono please?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文