编组公约C++ vs c#/mono
我有以下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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论