C++与Java内存共享技术:跨平台与跨语言实现指南

发布于:2025-07-04 ⋅ 阅读:(12) ⋅ 点赞:(0)

引言

在C++和Android项目移植过程中,内存共享是提高性能、减少数据拷贝的关键技术。本文解决了Windows 与 Android 平台处理内存共享问题,采用了会话管理机制保存了同一状态;还解决了C++项目移植在Android项目中依赖过多的问题,采用了Pimpl(Pointer to Implementation)设计模式 来隐藏实现细节,减少头文件依赖:

  1. Windows平台C++进程间的内存共享

  2. C++与Java间的内存共享(通过JNI)

一、Windows与Android内存共享实现

WIndows平台调用

在windows中,MeasurementCalcStep1 和 MeasurementCalcStep2 共享同一个 handle,而在 Android 中这两个步骤被分成了独立的 JNI 调用,导致 handle 状态丢失。

void* handle;
//第一步
bool AstriRoomMeasurementWrapper::MeasurementCalcStep1(const CHAR* scene_path,const CHAR* mesh_output_path,
	const CHAR* direpath, const CHAR* contour_xml)
{
	SetHardwareType(0);
	const std::string scenePath = scene_path;
	const std::string meshPath = mesh_output_path;
	const std::string direPath = direpath;
	const std::string tmp_room_contour_xml = contour_xml;
	mylog("\n\n\nMeasurementCalcStep1 Params to calc:");
	mylog("scene_path:" + scenePath);
	mylog("direpath:" + direPath);
	mylog("tmp_room_contour_xml:" + tmp_room_contour_xml);
	EnabledNewMeasureId(true);
	SetHardwareType(0);
	mylog("Calc Measurement start");

	handle = InitRoomScene();
	if (handle == nullptr) {
		mylog("InitRoomScene handle null!!!");
		return false;
	}
	bool res = ParseRoomScene(handle, scenePath, direPath, meshPath);
	if (!res) {
		mylog("ParseRoomScene fail");
		return false;
	}
	bool isXml = GetRoomContour(handle, tmp_room_contour_xml);
	mylog("GetRoomContour result:"+ isXml);
	return isXml;
}

//第二步
bool AstriRoomMeasurementWrapper::MeasurementCalcStep2(const CHAR* json_output_path, const CHAR* match_xml)
{
	MeasurementResult* result = new MeasurementResult();
	std::string room_contour = match_xml;
	std::string jsonPath = json_output_path;
	mylog("\n\n\MeasurementCalcStep2 Params to calc:");
	mylog("match_xml:" + room_contour);
	mylog("jsonPath:" + jsonPath);
	bool res = RoomMeasurement(handle, result, room_contour);
	if (!res) {
		mylog("RoomMeasurement fail");
		delete result;
		return false;
	}
	//GetMeasurementResult
	res = JsonFormat(result, jsonPath);
	if (!res) {
		mylog("JsonFormat fail");
		delete result;
		return false;
	}
	ReleaseRoomScene(handle);
	delete result;
	return true;
}

解决方案:跨平台状态管理

1.修改MeasurementHelper类

注释掉了类的构造和析构函数,增加了CreateSessionReleaseSession会话管理器函数。

class MeasurementHelper
{
public:
	/*MeasurementHelper() { handle = new MeasurementProcess(); }
	~MeasurementHelper() 
	{ 
		log_file_close();
		delete handle; handle = nullptr; 
	}*/

	MeasurementHelper() : handle(nullptr) {}

	~MeasurementHelper() {
		ReleaseSession();
	}
	void* CreateSession() {
		if (handle) {
			return nullptr;
		}

		handle = new MeasurementProcess();
		if (!handle) {
			return nullptr;
		}
		return static_cast<void*>(handle);
	}

	void ReleaseSession() {
		if (handle) {
			log_file_close();
			delete handle;
			handle = nullptr;
			scene_path.clear();
			output_path.clear();
		}
	}

	MeasurementHelper(const MeasurementHelper&) = delete;
	MeasurementHelper& operator=(const MeasurementHelper&) = delete;

	MeasurementHelper(MeasurementHelper&& other) noexcept
		: handle(other.handle),
		alignmentres(std::move(other.alignmentres)),
		scene_path(std::move(other.scene_path)),
		output_path(std::move(other.output_path))
	{
		other.handle = nullptr;
	}

	MeasurementHelper& operator=(MeasurementHelper&& other) noexcept {
		if (this != &other) {
			ReleaseSession();
			handle = other.handle;
			alignmentres = std::move(other.alignmentres);
			scene_path = std::move(other.scene_path);
			output_path = std::move(other.output_path);
			other.handle = nullptr;
		}
		return *this;
	}

	MeasurementProcess* GetHandle() { return handle; }

	bool Measurement(MeasurementResult* result, MeasurementResult_1* result_1, std::string room_contour_xml)
	{
		MeasurementProcess::OpenLogFile(output_path.substr(0, output_path.find_last_of("/")) + "/measureWithdrawinglog");
		log_info("The path of measureWithDrawinglog: %s", (output_path.substr(0, output_path.find_last_of("/")) + "/measureWithdrawinglog").c_str());
		log_info("Start measurement!!!");

		bool res = false;

		log_info("Measurement: before res = handle->Measurement");
		res = handle->Measurement(&alignmentres, true, room_contour_xml);
		log_info("Measurement: after res = handle->Measurement");
		if (!res)
			return res;
		if(IsOPTIMIZE_HOLE_BY_IMAGE())
#ifdef OPTIMIZE_HOLE_BY_IMAGE
#ifdef _WIN32
		make_shared<IPlaneLineByRgbd>(alignmentres, *handle);
#endif
#endif
		log_info("Measurement: before MeasurementResult");
		MesurementResult(result, result_1, handle);
		log_info("Measurement: after MeasurementResult");
		AlignmentResultToMesurementResult(result, alignmentres);
		log_info("Measurement: after AlignmentResultToMeasurementResult");
		std::vector<std::string> mesh_list;

		bool cardflag = false;
		log_info("Measurement: start save plane mesh");
		if (handle->SavePlaneMesh(scene_path, scene_path, alignmentres, mesh_list, output_path, result->cad_door, result->cad_window, cardflag))
			res = true;
		log_info("Measurement: save plane mesh successfully");

		return res;
	}

	bool  GetContourXML(const std::string& xml_path)
	{
		//xml_path = output_path + "/contour.xml";
		//xml_path =  "tmp_room_contour.xml";
		std::cout << "xml_path:" << xml_path << std::endl;
		//std::cout << "===test===" << std::endl;
		return handle->GetRoomContour(xml_path, &alignmentres);
	}

	bool ParseScene(std::string scene_path, std::string compass_path, std::string path)
	{
		MeasurementProcess::OpenLogFile(path.substr(0, path.find_last_of("/")) + "/parseScenelog");
		cout << "%$@#&^$* The path of the parseScenelog: " << path.substr(0, path.find_last_of("/")) << "/parseScenelog" << endl;
		log_info("The Path of ParseScenelog: %s", (path.substr(0, path.find_last_of("/")) + "/parseScenelog").c_str());
		log_info("Start Parse Scene!!!");

		this->scene_path = scene_path;
		this->output_path = path;
		g_meshPath = path;
#ifdef _WIN32
		imagePath = path.substr(0, path.find_last_of("\\")) + "\\contour.jpg";
#else
		imagePath = path.substr(0, path.find_last_of("/")) + "/contour.jpg";
#endif
		cloudPath = scene_path;
	
		CCompass compass;
		compass.ReadCompassByTxt(compass_path);
		log_info("Read Compass By Txt!!!");
	
		s_MeasurementErrorCode = MEASUREMENT_SUCCESS;
		
		handle->SetCustomerName(MEASUREMENT_CUSTOMER_UNRE);
		log_info("Get handle success!!!");

		return handle->ParseScene(scene_path, "", &alignmentres);
	}

	
private:
	MeasurementProcess* handle;

	//MeasurementResult  result;
	AlignmentResult    alignmentres;
	std::string        scene_path;
	std::string        output_path;

};

2.创建了全局管理器

MeasurementSessionManager.h

#ifndef MEASUREMENT_SESSION_MANAGER_H
#define MEASUREMENT_SESSION_MANAGER_H

#include <map>
#include <mutex>
#include <memory>
#include "MeasurementAPI.h"

class MeasurementSessionManager {
public:
	static MeasurementSessionManager& Instance() {
		static MeasurementSessionManager instance;
		return instance;
	}

	void* CreateSession();

	MeasurementHelper* GetHelper(void* sessionHandle);

	bool ReleaseSession(void* sessionHandle);

	void ReleaseAllSessions();

	MeasurementSessionManager(const MeasurementSessionManager&) = delete;
	MeasurementSessionManager& operator=(const MeasurementSessionManager&) = delete;

private:
	MeasurementSessionManager() = default;

	std::map<void*, std::unique_ptr<MeasurementHelper>> sessions_;

	std::mutex mutex_;
};

#endif // MEASUREMENT_SESSION_MANAGER_H

MeasurementSessionManager.cpp

#include "MeasurementSessionManager.h"

void* MeasurementSessionManager::CreateSession() {
	std::lock_guard<std::mutex> lock(mutex_);

	auto helper = std::make_unique<MeasurementHelper>();

	void* handle = helper->CreateSession();
	if (!handle) {
		return nullptr;
	}
	sessions_[handle] = std::move(helper);
	return handle;
}

MeasurementHelper* MeasurementSessionManager::GetHelper(void* sessionHandle) {
	std::lock_guard<std::mutex> lock(mutex_);
	auto it = sessions_.find(sessionHandle);
	if (it != sessions_.end()) {
		return it->second.get();
	}
	return nullptr;
}

bool MeasurementSessionManager::ReleaseSession(void* sessionHandle) {
	std::lock_guard<std::mutex> lock(mutex_);
	auto it = sessions_.find(sessionHandle);
	if (it != sessions_.end()) {
		it->second->ReleaseSession();
		sessions_.erase(it);
		return true;
	}
	return false;
}

void MeasurementSessionManager::ReleaseAllSessions() {
	std::lock_guard<std::mutex> lock(mutex_);
	for (auto& pair : sessions_) {
		pair.second->ReleaseSession();
	}
	sessions_.clear();
}

二、使用Pimpl设计模式,去除MeasurementProcess.h依赖

由于在MeasurementHelper类中引用了MeasurementProcess结构体在MeasurementProcess.h中,而MeasurementProcess.h文件中依赖耦合了过多的头文件,所以采用了Pimpl设计模式,分离出来了需要的函数,避免输出的头文件中依赖耦合过多的文件导致难以移植

对上述代码中MeasurementHelper类的实现,分别在.h和.cpp文件中做了以下修改

改造步骤

  1. 创建实现类封装细节
    将 MeasurementHelper 的实现细节转移到独立的实现类中。

  2. 使用前置声明替代头文件包含
    在头文件中用前置声明代替 #include "MeasurementProcess.h"

  3. 分离接口与实现
    通过指针间接访问核心功能,避免暴露内部依赖。

DLL.h

/*
Function:MeasurementHelper with drawing matching
*/
class MeasurementHelper {
public:
	MeasurementHelper();
	~MeasurementHelper();

	MeasurementHelper(const MeasurementHelper&) = delete;
	MeasurementHelper& operator = (const MeasurementHelper&) = delete;

	MeasurementHelper(MeasurementHelper&& other) noexcept;
	MeasurementHelper& operator = (MeasurementHelper&& other) noexcept;

	void* CreateSession();
	void ReleaseSession();
	bool Measurement(MeasurementResult* result, MeasurementResult_1* result_1, std::string room_contour_xml);
	bool GetContourXML(const std::string& xml_path);
	bool ParseScene(std::string scene_path, std::string compass_path, std::string path);
private:
	struct Impl;
	std::unique_ptr<Impl> impl;

};

DLL.cpp 实现

struct MeasurementHelper::Impl{
	MeasurementProcess* handle = nullptr;
	AlignmentResult alignmentres;
	std::string scene_path;
	std::string output_path;

	void* CreateSession() {
		if (handle) return nullptr;
		handle = new MeasurementProcess();
		return static_cast<void*>(handle);
	}

	void ReleaseSession() {
		if (handle) {
			log_file_close();
			delete handle;
			handle = nullptr;
			scene_path.clear();
			output_path.clear();
		}
	}

	bool Measurement(MeasurementResult* result, MeasurementResult_1* result_1, std::string room_contour_xml)
	{
		MeasurementProcess::OpenLogFile(output_path.substr(0, output_path.find_last_of("/")) + "/measureWithdrawinglog");
		log_info("The path of measureWithDrawinglog: %s", (output_path.substr(0, output_path.find_last_of("/")) + "/measureWithdrawinglog").c_str());
		log_info("Start measurement!!!");

		bool res = false;

		log_info("Measurement: before res = handle->Measurement");
		res = handle->Measurement(&alignmentres, true, room_contour_xml);
		log_info("Measurement: after res = handle->Measurement");
		if (!res)
			return res;
		if (IsOPTIMIZE_HOLE_BY_IMAGE())
#ifdef OPTIMIZE_HOLE_BY_IMAGE
#ifdef _WIN32
			make_shared<IPlaneLineByRgbd>(alignmentres, *handle);
#endif
#endif
		log_info("Measurement: before MeasurementResult");
		MesurementResult(result, result_1, handle);
		log_info("Measurement: after MeasurementResult");
		AlignmentResultToMesurementResult(result, alignmentres);
		log_info("Measurement: after AlignmentResultToMeasurementResult");
		std::vector<std::string> mesh_list;

		bool cardflag = false;
		log_info("Measurement: start save plane mesh");
		if (handle->SavePlaneMesh(scene_path, scene_path, alignmentres, mesh_list, output_path, result->cad_door, result->cad_window, cardflag))
			res = true;
		log_info("Measurement: save plane mesh successfully");

		return res;
	}

	bool  GetContourXML(const std::string& xml_path)
	{
		//xml_path = output_path + "/contour.xml";
		//xml_path =  "tmp_room_contour.xml";
		std::cout << "xml_path:" << xml_path << std::endl;
		//std::cout << "===test===" << std::endl;
		return handle->GetRoomContour(xml_path, &alignmentres);
	}

	bool ParseScene(std::string scene_path, std::string compass_path, std::string path)
	{
		MeasurementProcess::OpenLogFile(path.substr(0, path.find_last_of("/")) + "/parseScenelog");
		cout << "%$@#&^$* The path of the parseScenelog: " << path.substr(0, path.find_last_of("/")) << "/parseScenelog" << endl;
		log_info("The Path of ParseScenelog: %s", (path.substr(0, path.find_last_of("/")) + "/parseScenelog").c_str());
		log_info("Start Parse Scene!!!");

		this->scene_path = scene_path;
		this->output_path = path;
		g_meshPath = path;
#ifdef _WIN32
		imagePath = path.substr(0, path.find_last_of("\\")) + "\\contour.jpg";
#else
		imagePath = path.substr(0, path.find_last_of("/")) + "/contour.jpg";
#endif
		cloudPath = scene_path;

		CCompass compass;
		compass.ReadCompassByTxt(compass_path);
		log_info("Read Compass By Txt!!!");

		s_MeasurementErrorCode = MEASUREMENT_SUCCESS;

		handle->SetCustomerName(MEASUREMENT_CUSTOMER_UNRE);
		log_info("Get handle success!!!");

		return handle->ParseScene(scene_path, "", &alignmentres);
	}
};

MeasurementHelper::MeasurementHelper() : impl(std::make_unique<Impl>()){}
MeasurementHelper::~MeasurementHelper() = default;

MeasurementHelper::MeasurementHelper(MeasurementHelper&& other) noexcept = default;

MeasurementHelper& MeasurementHelper::operator=(MeasurementHelper&& other) noexcept = default;

void* MeasurementHelper::CreateSession() {
	return impl->CreateSession();
}

void MeasurementHelper::ReleaseSession() {
	impl->ReleaseSession();
}

bool MeasurementHelper::Measurement(MeasurementResult* result, MeasurementResult_1* result_1,
	std::string room_contour_xml) {
	return impl->Measurement(result, result_1, room_contour_xml);
}

bool MeasurementHelper::GetContourXML(const std::string& xml_path) {
	return impl->GetContourXML(xml_path);
}

bool MeasurementHelper::ParseScene(std::string scene_path,
	std::string compass_path,
	std::string path) {
	return impl->ParseScene(scene_path, compass_path, path);
}

三、Android中引用

JNI内存共享架构

整体架构关系

JNI.cpp

本地接口层

  • 实现Java中声明的native方法

  • 在C++中处理Java传入的参数

  • 调用C++核心功能

  • 返回结果给Java层

#include <jni.h>
#include <string>
#include "MeasurementAPI.h"
#include "MeasurementConfig.h"
#include "MeasurementSessionManager.h"
#include "android/log.h"

#define LOG_TAG    "native-lib"
#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

std::string jstringToString(JNIEnv* env, jstring jstr) {
    if (!jstr) return "";

    const char* cstr = env->GetStringUTFChars(jstr, nullptr);
    std::string result(cstr);
    env->ReleaseStringUTFChars(jstr, cstr);

    return result;
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_unre_SDK_MeasureSDK_StartRoomMeasurement(
        JNIEnv* env,
        jclass clazz, jstring scene_path, jstring cad_path, jstring compass_path, jstring ruler_json, jstring meshPath, jstring jsonPath) {

    LOGI("!!!!!!!!StartMeasurement!!!!!!!!!!! !  %s\n", " 0 ");
    std::string hello = "Hello from C++";

    const char *Scene_path = env->GetStringUTFChars(scene_path, nullptr);
    std::string c_Scene_path =std::string(Scene_path);
    //std::string x_Scene_path =JniJavaToStdString(env, scene_path);

    const char *Cad_path = env->GetStringUTFChars(cad_path, nullptr);
    std::string c_Cad_path = std::string(Cad_path);

    const char *Compass_path = env->GetStringUTFChars(compass_path, nullptr);
    std::string c_Compass_path = std::string(Compass_path);

    const char *Ruler_json = env->GetStringUTFChars(ruler_json, nullptr);
    std::string c_Ruler_json = std::string(Ruler_json);

    const char *MeshPath = env->GetStringUTFChars(meshPath, nullptr);
    std::string c_MeshPath = std::string (MeshPath);

    const char *JsonPath = env->GetStringUTFChars(jsonPath, nullptr);
    std::string c_JsonPath = std::string (JsonPath);
    auto* result = new MeasurementResult();
    auto* result_1 = new MeasurementResult_1();

    LOGI("路径配置完成  %s\n", " 1 ");

    //hello += "Hello from TestRoomMeasurement";
    //std::cout << "Hello from TestRoomMeasurement" << std::endl;

    LOGI("The path of c_Ruler_json:  %s\n", c_Ruler_json.c_str());
    SetAllRulersJson(c_Ruler_json);
    LOGI("测量模式设置完成  %s\n", " 2 ");
    SetHardwareType(0);

    bool b;
    b = StartMeasurementAndSaveMesh_Android(static_cast<MEASUREMENT_CUSTOMER_NAME>(0x00000001), c_Scene_path, c_Cad_path, result, result_1, c_Compass_path, c_MeshPath);
    LOGI("The size of bim_info_hole_details:   %zu\n", result->bim_info_hole_details.size());

    if (c_JsonPath.empty())
    {
        return (jstring) L"";
    }

//    unsigned len = c_JsonPath.size() + 1;
//    setlocale(LC_CTYPE, "en_US.UTF-8");
//    auto *p = new wchar_t[len];
//    mbstowcs(p, c_JsonPath.c_str(), len);
//    std::wstring w_JsonPath(p);
//    delete[] p;

//    LOGI("w_JsonPath:   %ls\n", w_JsonPath.c_str());
//    std::wcout << "w_JsonPath:  " << w_JsonPath.c_str() << std::endl;
    LOGI("Start output json!!!");

    bool J;
    J = JsonFormat(result, result_1, c_JsonPath);
    LOGI("Ended output json!!!");
    //delete result;
    LOGI("If successfully output json:   %d\n", J);

//    std::string bool_b = &"是否调用成功:" [ b];
    LOGI("是否調用成功:  %d\n", b);
//    return env->NewStringUTF(bool_b.c_str());

    env->ReleaseStringUTFChars(scene_path, Scene_path);
    env->ReleaseStringUTFChars(cad_path, Cad_path);
    env->ReleaseStringUTFChars(compass_path, Compass_path);
    env->ReleaseStringUTFChars(ruler_json, Ruler_json);
    env->ReleaseStringUTFChars(meshPath, MeshPath);
    env->ReleaseStringUTFChars(jsonPath, JsonPath);

    env->DeleteLocalRef(scene_path);
    env->DeleteLocalRef(cad_path);
    env->DeleteLocalRef(compass_path);
    env->DeleteLocalRef(ruler_json);
    env->DeleteLocalRef(meshPath);
    env->DeleteLocalRef(jsonPath);

    delete result;
    delete result_1;

    return env->NewStringUTF(hello.c_str());
}

extern "C"
JNIEXPORT jstring JNICALL
Java_com_unre_SDK_MeasureSDK_StartRoomMeasurementFactory(JNIEnv *env, jclass clazz,
                                                         jstring scene_path, jstring cad_path,
                                                         jstring compass_path, jstring meshPath,

                                                         jstring jsonPath) {
    // TODO: implement StartRoomMeasurementFactory()
    LOGI("!!!!!!!!StartMeasurement!!!!!!!!!!! !  %s\n", " 0 ");
    std::string hello = "Hello from C++";

    const char *Scene_path = env->GetStringUTFChars(scene_path, nullptr);
    std::string c_Scene_path =std::string(Scene_path);
    //std::string x_Scene_path =JniJavaToStdString(env, scene_path);

    const char *Cad_path = env->GetStringUTFChars(cad_path, nullptr);
    std::string c_Cad_path = std::string(Cad_path);

    const char *Compass_path = env->GetStringUTFChars(compass_path, nullptr);
    std::string c_Compass_path = std::string(Compass_path);

    const char *MeshPath = env->GetStringUTFChars(meshPath, nullptr);
    std::string c_MeshPath = std::string (MeshPath);

    const char *JsonPath = env->GetStringUTFChars(jsonPath, nullptr);
    std::string c_JsonPath = std::string (JsonPath);
    auto* result = new MeasurementResult();
    auto* result_1 = new MeasurementResult_1();

    LOGI("路径配置完成  %s\n", " 1 ");

    bool b;
    b = StartMeasurementAndSaveMesh_Android(static_cast<MEASUREMENT_CUSTOMER_NAME>(0x00000001), c_Scene_path, c_Cad_path, result, result_1, c_Compass_path, c_MeshPath);
    LOGI("The size of bim_info_hole_details:   %zu\n", result->bim_info_hole_details.size());

    if (c_JsonPath.empty())
    {
        return (jstring) L"";
    }

    unsigned len = c_JsonPath.size() + 1;
    setlocale(LC_CTYPE, "en_US.UTF-8");
    auto *p = new wchar_t[len];
    mbstowcs(p, c_JsonPath.c_str(), len);
    std::wstring w_JsonPath(p);
    delete[] p;

    LOGI("w_JsonPath:   %ls\n", w_JsonPath.c_str());
//    std::wcout << "w_JsonPath:  " << w_JsonPath.c_str() << std::endl;
    LOGI("Start output json!!!");

    bool J;
    J = JsonFormat(result, result_1, c_JsonPath);
    LOGI("Ended output json!!!");
    LOGI("If successfully output json:   %d\n", J);

//    std::string bool_b = &"是否调用成功:" [ b];
    LOGI("是否調用成功:  %d\n", b);
//    return env->NewStringUTF(bool_b.c_str());

    env->ReleaseStringUTFChars(scene_path, Scene_path);
    env->ReleaseStringUTFChars(cad_path, Cad_path);
    env->ReleaseStringUTFChars(compass_path, Compass_path);
    env->ReleaseStringUTFChars(meshPath, MeshPath);
    env->ReleaseStringUTFChars(jsonPath, JsonPath);

    env->DeleteLocalRef(scene_path);
    env->DeleteLocalRef(cad_path);
    env->DeleteLocalRef(compass_path);
    env->DeleteLocalRef(meshPath);
    env->DeleteLocalRef(jsonPath);

    delete result;
    delete result_1;

    return env->NewStringUTF(hello.c_str());

}

extern "C"
JNIEXPORT jlong JNICALL
Java_com_unre_SDK_MeasureSDK_createSession(
        JNIEnv* env, jclass clazz) {

    return reinterpret_cast<jlong>(
            MeasurementSessionManager::Instance().CreateSession()
    );
}


extern "C"
JNIEXPORT bool JNICALL
Java_com_unre_SDK_MeasureSDK_ParseRoomScene(JNIEnv *env, jclass clazz,
                                            jlong session_handle,
                                            jstring scene_path,
                                            jstring compass_path,
                                            jstring ruler_json,
                                            jstring mesh_path,
                                            jstring contour_xml) {
    void* sessionHandle = reinterpret_cast<void*>(session_handle);
    auto helper = MeasurementSessionManager::Instance().GetHelper(sessionHandle);
    std::string scene = jstringToString(env, scene_path);
    std::string compass = jstringToString(env, compass_path);
    std::string ruler = jstringToString(env, ruler_json);
    std::string mesh = jstringToString(env, mesh_path);
    std::string contour = jstringToString(env, contour_xml);

//    const char *Scene_path = env->GetStringUTFChars(scene_path, nullptr);
//    std::string c_Scene_path = std::string(Scene_path);
//
//    const char *Compass_path = env->GetStringUTFChars(compass_path, nullptr);
//    std::string c_Compass_path = std::string (Compass_path);
//
//    const char *Ruler_json = env->GetStringUTFChars(ruler_json, nullptr);
//    std::string c_Ruler_json = std::string (Ruler_json);
//
//    const char *Mesh_path = env->GetStringUTFChars(mesh_path, nullptr);
//    std::string c_Mesh_path = std::string(Mesh_path);
//
//    const char *Contour_xml = env->GetStringUTFChars(contour_xml, nullptr);
//    std::string c_Contour_xml = std::string(Contour_xml);

    SetAllRulersJson(ruler);

    SetHardwareType(0);

    bool parseSuccess = helper->ParseScene(scene, compass, mesh);
    if (!parseSuccess) {
        return JNI_FALSE;
    }

    // 获取轮廓 XML
    bool contourSuccess = helper->GetContourXML(contour);
    return contourSuccess ? JNI_TRUE : JNI_FALSE;
}

extern "C"
JNIEXPORT jboolean  JNICALL
Java_com_unre_SDK_MeasureSDK_RoomMeasurement(JNIEnv *env, jclass clazz,
                                             jlong session_handle,
                                             jstring subwall_contour,
                                             jstring jsonPath) {
    void* sessionHandle = reinterpret_cast<void*>(session_handle);
    auto helper = MeasurementSessionManager::Instance().GetHelper(sessionHandle);

    const char *Subwall_contour = env->GetStringUTFChars(subwall_contour, nullptr);
    std::string c_Subwall_contour = std::string(Subwall_contour);

    const char *JsonPath = env->GetStringUTFChars(jsonPath, nullptr);
    std::string c_JsonPath = std::string(JsonPath);

    auto* result = new MeasurementResult();
    auto* result_1 = new MeasurementResult_1();

    bool measureSuccess = helper->Measurement(result,result_1,c_Subwall_contour);
    if (!measureSuccess) {
        return JNI_FALSE;
    }

    bool jsonSuccess = JsonFormat(result, result_1,c_JsonPath);
    MeasurementSessionManager::Instance().ReleaseSession(sessionHandle);

    delete result;
    delete result_1;

    return jsonSuccess ? JNI_TRUE : JNI_FALSE;

//    RoomMeasurement(handle, result, result_1, c_Subwall_contour);
//
//    JsonFormat(result, result_1, c_JsonPath);
//
//    ReleaseRoomScene(handle);
}

extern "C"
JNIEXPORT jboolean  JNICALL
Java_com_unre_SDK_MeasureSDK_releaseSession(
        JNIEnv* env, jclass clazz, jlong session_handle) {

    void* sessionHandle = reinterpret_cast<void*>(session_handle);
    MeasurementSessionManager::Instance().ReleaseSession(sessionHandle);
}

MeasureSDK.java

Java与C++之间的桥梁

  • 加载本地库

  • 声明native方法接口

  • 封装C++功能为Java可调用的API

testroommeasurement是整合C++项目在cmakelist项目中声明的项目名称。

package com.unre.SDK;

public class MeasureSDK {
    static{
        System.loadLibrary("testroommeasurement");
    }
    public static native long createSession();
    public static native String StartRoomMeasurement(String scene_path, String cad_path, String compass_path, String ruler_json, String meshPath, String jsonPath);

    //factory no ruler_json
    public static native String StartRoomMeasurementFactory(String scene_path, String cad_path, String compass_path, String meshPath, String jsonPath);
    //    public native String testJNI();

    public static native boolean ParseRoomScene(
            long sessionHandle,
            String scenePath, String compassPath,
            String rulerJson, String meshPath,
            String contourXml);

    public static native boolean RoomMeasurement(
            long sessionHandle,
            String matchXml, String jsonPath);
    public static native void releaseSession(long sessionHandle);
}

RoomMeasurementService.java

系统服务的Android实现

  • 作为后台Service长期运行

  • 通过AIDL暴露服务接口

  • 管理测量会话的生命周期

  • 调用MeasureSDK执行实际测量

package com.unre.ucl360.measurementservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import androidx.annotation.Nullable;
import com.unre.SDK.MeasureSDK;
import com.unre.ucl360.BimMatchService.BimMatchAidlInterface;

import java.io.File;
import java.io.InterruptedIOException;

public class RoomMeasurementService extends Service
{
    private final RMtAidlInterface.Stub mRMtAidlInterface = new RMtAidlInterface.Stub()
    {
        BimMatchAidlInterface mBimMatchAidlInterface;
        private long currentSessionId = 0;

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException
        {

        }

        @Override
        public boolean JRoomMeasurement(String scenePath, String compass_path, String ruler_json, String cad_path, String meshPath, String jsonPath) throws RemoteException
        {
            File path = new File(jsonPath);
            String parentPath = path.getParent();

            AssetsCopyTOSDcard assetsCopyTOSDcard = new AssetsCopyTOSDcard(getApplicationContext());
            assetsCopyTOSDcard.AssetToSD("config_file", parentPath);

            String M_results = MeasureSDK.StartRoomMeasurement(scenePath, cad_path, compass_path, ruler_json, meshPath, jsonPath);
            Log.d("TAG","M_results "+M_results);
            File jsonFile = new File(jsonPath);
            return jsonFile.length() != 0;

        }

        public boolean JRoomMeasurementFactory(String scenePath, String compass_path, String cad_path, String meshPath, String jsonPath) throws RemoteException
        {
            File path = new File(jsonPath);
            String parentPath = path.getParent();

            AssetsCopyTOSDcard assetsCopyTOSDcard = new AssetsCopyTOSDcard(getApplicationContext());
            assetsCopyTOSDcard.AssetToSD("config_file", parentPath);
            String M_results = MeasureSDK.StartRoomMeasurementFactory(scenePath, cad_path, compass_path, meshPath, jsonPath);
            File jsonFile = new File(jsonPath);
            return jsonFile.length() != 0;

        }

        @Override
        public void ParseRoomScene(String scenePath, String compass_path,
                                   String ruler_json, String meshPath,
                                   String contour_xml) throws RemoteException {

            File meshDir = new File(meshPath);
            if (!meshDir.exists()) {
                meshDir.mkdirs();
            }

            AssetsCopyTOSDcard assetsCopy = new AssetsCopyTOSDcard(getApplicationContext());
            assetsCopy.AssetToSD("config_file", meshPath);

            currentSessionId = MeasureSDK.createSession();
            if (currentSessionId == 0) {
                Log.e("Measurement", "Failed to create session");
            }

            boolean success = MeasureSDK.ParseRoomScene(
                    currentSessionId,scenePath, compass_path, ruler_json, meshPath, contour_xml);

            if (!success) {
                throw new RemoteException("ParseRoomScene failed");
            }
        }

        public boolean RoomMeasurementAndSaveData(String jsonPath)
        {
            File Path = new File(jsonPath);
            String ParentPath = Path.getParent();
            String subwall_contour = ParentPath + "SubWalls.xml";

            MeasureSDK.RoomMeasurement(currentSessionId,subwall_contour, jsonPath);
            MeasureSDK.releaseSession(currentSessionId);
            currentSessionId = 0;
            File jsonFile = new File(jsonPath);
            return jsonFile.length() != 0;
        }

        public boolean JRoomMeasurementWithBluePrint(String scenePath, String compass_path, String ruler_json, String meshPath, String contour_xml, String drawPath, String xmlPath, String stage, String stationId, String preMatchPath, String cadId, String xmlId, String matchResult, String jsonPath)
        {
            String lock = "The first is existed!";

            new Thread(()-> {
                try{
                    mRMtAidlInterface.ParseRoomScene(scenePath, compass_path, ruler_json, meshPath, contour_xml);

                    File file = new File(preMatchPath);
                    if (!file.exists())
                    {
                        for (int i = 0; i < 2; i++)
                        {
                            if (mBimMatchAidlInterface != null) {
                                mBimMatchAidlInterface.JScanMatch(drawPath, xmlPath, stage, stationId, preMatchPath, cadId, xmlId, matchResult);
                            } else {
                                Log.e("MainActivity", "BimMatchAidlInterface is not bound.");
                            }
                        }
                    }
                    else
                    {
                        if (mBimMatchAidlInterface != null) {
                            mBimMatchAidlInterface.JScanMatch(drawPath, xmlPath, stage, stationId, preMatchPath, cadId, xmlId, matchResult);
                        } else {
                            Log.e("MainActivity", "BimMatchAidlInterface is not bound.");
                        }
                    }

                    Log.i("before RoomMeasurementAndSaveData", "before RoomMeasurementAndSaveData");
                    mRMtAidlInterface.RoomMeasurementAndSaveData(jsonPath);

                } catch (Exception e) {
                    throw new RuntimeException(e);
                }

                synchronized (lock) {
                    try {
                        lock.notifyAll();
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }

            }, "First").start();

            new Thread(()-> {
                synchronized (lock) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }

                try {
                    mRMtAidlInterface.ParseRoomScene(scenePath, compass_path, ruler_json, meshPath, contour_xml);

                    File file = new File(preMatchPath);
                    if (!file.exists())
                    {
                        for (int i = 0; i < 2; i++)
                        {
                            if (mBimMatchAidlInterface != null) {
                                mBimMatchAidlInterface.JScanMatch(drawPath, xmlPath, stage, stationId, preMatchPath, cadId, xmlId, matchResult);
                            } else {
                                Log.e("MainActivity", "BimMatchAidlInterface is not bound.");
                            }
                        }
                    }
                    else {
                        if (mBimMatchAidlInterface != null) {
                            mBimMatchAidlInterface.JScanMatch(drawPath, xmlPath, stage, stationId, preMatchPath, cadId, xmlId, matchResult);
                        } else {
                            Log.e("MainActivity", "BimMatchAidlInterface is not bound.");
                        }
                    }

                    mRMtAidlInterface.RoomMeasurementAndSaveData(jsonPath);

                } catch (RemoteException e) {
                    throw new RuntimeException(e);
                }

//                    lock.notifyAll();


            }, "second").start();

            return true;
        }

//        public boolean JRoomMeasurementWithBluePrint(String scenePath, String compass_path, String ruler_json, String contour_xml, String meshPath, String jsonPath)
//        {
//            boolean ret = MeasureSDK.ParseRoomScene(scenePath, compass_path, ruler_json, meshPath, contour_xml);
//
//            if (!ret)
//            {
//                Log.i("Send error info", "parseRoomScene fail!!");
//            }
//
//            String lock = "It's a match!";
//            new Thread(()->{
//                synchronized (lock)
//                {
//                    try{
//                        lock.notify();
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                }
//            },"t1").start();
//
//            System.out.println("已通知去匹配了!");
//
//            new Thread(()->{
//                synchronized (lock)
//                {
//                    try {
//                        lock.wait();
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                }
//            },"t2").start();
//
//            System.out.println("匹配结束,等到匹配结束的信号!");
//
//
//            File Path = new File(jsonPath);
//            String ParentPath = Path.getParent();
//            String match_xml = ParentPath + "match_result.json";
//
//            MeasureSDK.RoomMeasurement(match_xml, jsonPath);
//
//            return true;
//        }

//        public boolean JRoomMeasurement_OwnBlueprint(String scenePath, String compass_path, String subwall_contour, String meshPath, String jsonPath)
//        {
//            MeasureSDK.ParseRoomScene(scenePath, compass_path, meshPath);
//
//            MeasureSDK.RoomMeasurement(subwall_contour, jsonPath);
//
//            File jsonFile = new File(jsonPath);
//            return jsonFile.length() != 0;
//        }
    };


    @Override
    public void onCreate()
    {
        super.onCreate();
//        FileUtils.creatPath();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mRMtAidlInterface;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

AIDL (Android Interface Definition Language) - 跨进程通信层

进程间通信(IPC)的契约定义

  • 定义服务接口和方法签名

  • 生成跨进程通信的代理代码

  • 处理进程间数据编组(marshalling)

/*
 * This file is auto-generated.  DO NOT MODIFY.
 */
package com.unre.ucl360.measurementservice;
// Declare any non-default types here with import statements
public interface RMtAidlInterface extends android.os.IInterface
{
  /** Default implementation for RMtAidlInterface. */
  public static class Default implements com.unre.ucl360.measurementservice.RMtAidlInterface
  {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException
    {
    }
    /**
     * JRoomMeasurement函数中的参数皆为路径:
     * scenePath: 点云路径,文件类型为 pts、ptsen
     * compass_path: 方位文件路径———— dire.txt
     * Ruler_json: 用户设置的测量模式————ruler.json
     * cad_path: CAD文件路径
     * meshPath: 输出mesh.obj相关文件的路径
     * jsonPath:output.json输出路径
     */
    // no Blueprint
    @Override public boolean JRoomMeasurement(java.lang.String scenePath, java.lang.String compass_path, java.lang.String Ruler_json, java.lang.String cad_path, java.lang.String meshPath, java.lang.String jsonPath) throws android.os.RemoteException
    {
      return false;
    }
    @Override public boolean JRoomMeasurementFactory(java.lang.String scenePath, java.lang.String compass_path, java.lang.String cad_path, java.lang.String meshPath, java.lang.String jsonPath) throws android.os.RemoteException
    {
      return false;
    }
    /**
     * The arguements of the API JScanMatch:
     * "-d",  ------- drawPath
     * "-x",  ------- xmlPath
     * "-s",  ------- stage
     * "-a",  ------- stationId
     * "-pm", ------- preMatchPath
     * "-im", ------- cadId
     * "-is", ------- xmlId
     * "-m",  ------- resultPath
     */
    // Own Blueprint
    /**
     * The arguements of the API ParseRoomScene
     * scene_path,      // 点云文件路径
     * compass_path,    // 方位文件路径
     * ruler_json,      // 测量规则配置文件
     * mesh_path,       // 网格输出路径
     * contour_xml      // 房间轮廓输出路径,输出为XML格式文件
     */
    @Override public void ParseRoomScene(java.lang.String scenePath, java.lang.String compass_path, java.lang.String ruler_json, java.lang.String meshPath, java.lang.String contour_xml) throws android.os.RemoteException
    {
    }
    @Override public boolean RoomMeasurementAndSaveData(java.lang.String jsonPath) throws android.os.RemoteException
    {
      return false;
    }
    @Override public boolean JRoomMeasurementWithBluePrint(java.lang.String scenePath, java.lang.String compass_path, java.lang.String ruler_json, java.lang.String meshPath, java.lang.String contour_xml, java.lang.String drawPath, java.lang.String xmlPath, java.lang.String stage, java.lang.String stationId, java.lang.String preMatchPath, java.lang.String cadId, java.lang.String xmlId, java.lang.String matchResult, java.lang.String jsonPath) throws android.os.RemoteException
    {
      return false;
    }
    @Override
    public android.os.IBinder asBinder() {
      return null;
    }
  }
  /** Local-side IPC implementation stub class. */
  public static abstract class Stub extends android.os.Binder implements com.unre.ucl360.measurementservice.RMtAidlInterface
  {
    /** Construct the stub at attach it to the interface. */
    public Stub()
    {
      this.attachInterface(this, DESCRIPTOR);
    }
    /**
     * Cast an IBinder object into an com.unre.ucl360.measurementservice.RMtAidlInterface interface,
     * generating a proxy if needed.
     */
    public static com.unre.ucl360.measurementservice.RMtAidlInterface asInterface(android.os.IBinder obj)
    {
      if ((obj==null)) {
        return null;
      }
      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
      if (((iin!=null)&&(iin instanceof com.unre.ucl360.measurementservice.RMtAidlInterface))) {
        return ((com.unre.ucl360.measurementservice.RMtAidlInterface)iin);
      }
      return new com.unre.ucl360.measurementservice.RMtAidlInterface.Stub.Proxy(obj);
    }
    @Override public android.os.IBinder asBinder()
    {
      return this;
    }
    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
    {
      java.lang.String descriptor = DESCRIPTOR;
      if (code >= android.os.IBinder.FIRST_CALL_TRANSACTION && code <= android.os.IBinder.LAST_CALL_TRANSACTION) {
        data.enforceInterface(descriptor);
      }
      switch (code)
      {
        case INTERFACE_TRANSACTION:
        {
          reply.writeString(descriptor);
          return true;
        }
      }
      switch (code)
      {
        case TRANSACTION_basicTypes:
        {
          int _arg0;
          _arg0 = data.readInt();
          long _arg1;
          _arg1 = data.readLong();
          boolean _arg2;
          _arg2 = (0!=data.readInt());
          float _arg3;
          _arg3 = data.readFloat();
          double _arg4;
          _arg4 = data.readDouble();
          java.lang.String _arg5;
          _arg5 = data.readString();
          this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
          reply.writeNoException();
          break;
        }
        case TRANSACTION_JRoomMeasurement:
        {
          java.lang.String _arg0;
          _arg0 = data.readString();
          java.lang.String _arg1;
          _arg1 = data.readString();
          java.lang.String _arg2;
          _arg2 = data.readString();
          java.lang.String _arg3;
          _arg3 = data.readString();
          java.lang.String _arg4;
          _arg4 = data.readString();
          java.lang.String _arg5;
          _arg5 = data.readString();
          boolean _result = this.JRoomMeasurement(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
          reply.writeNoException();
          reply.writeInt(((_result)?(1):(0)));
          break;
        }
        case TRANSACTION_JRoomMeasurementFactory:
        {
          java.lang.String _arg0;
          _arg0 = data.readString();
          java.lang.String _arg1;
          _arg1 = data.readString();
          java.lang.String _arg2;
          _arg2 = data.readString();
          java.lang.String _arg3;
          _arg3 = data.readString();
          java.lang.String _arg4;
          _arg4 = data.readString();
          boolean _result = this.JRoomMeasurementFactory(_arg0, _arg1, _arg2, _arg3, _arg4);
          reply.writeNoException();
          reply.writeInt(((_result)?(1):(0)));
          break;
        }
        case TRANSACTION_ParseRoomScene:
        {
          java.lang.String _arg0;
          _arg0 = data.readString();
          java.lang.String _arg1;
          _arg1 = data.readString();
          java.lang.String _arg2;
          _arg2 = data.readString();
          java.lang.String _arg3;
          _arg3 = data.readString();
          java.lang.String _arg4;
          _arg4 = data.readString();
          this.ParseRoomScene(_arg0, _arg1, _arg2, _arg3, _arg4);
          reply.writeNoException();
          break;
        }
        case TRANSACTION_RoomMeasurementAndSaveData:
        {
          java.lang.String _arg0;
          _arg0 = data.readString();
          boolean _result = this.RoomMeasurementAndSaveData(_arg0);
          reply.writeNoException();
          reply.writeInt(((_result)?(1):(0)));
          break;
        }
        case TRANSACTION_JRoomMeasurementWithBluePrint:
        {
          java.lang.String _arg0;
          _arg0 = data.readString();
          java.lang.String _arg1;
          _arg1 = data.readString();
          java.lang.String _arg2;
          _arg2 = data.readString();
          java.lang.String _arg3;
          _arg3 = data.readString();
          java.lang.String _arg4;
          _arg4 = data.readString();
          java.lang.String _arg5;
          _arg5 = data.readString();
          java.lang.String _arg6;
          _arg6 = data.readString();
          java.lang.String _arg7;
          _arg7 = data.readString();
          java.lang.String _arg8;
          _arg8 = data.readString();
          java.lang.String _arg9;
          _arg9 = data.readString();
          java.lang.String _arg10;
          _arg10 = data.readString();
          java.lang.String _arg11;
          _arg11 = data.readString();
          java.lang.String _arg12;
          _arg12 = data.readString();
          java.lang.String _arg13;
          _arg13 = data.readString();
          boolean _result = this.JRoomMeasurementWithBluePrint(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11, _arg12, _arg13);
          reply.writeNoException();
          reply.writeInt(((_result)?(1):(0)));
          break;
        }
        default:
        {
          return super.onTransact(code, data, reply, flags);
        }
      }
      return true;
    }
    private static class Proxy implements com.unre.ucl360.measurementservice.RMtAidlInterface
    {
      private android.os.IBinder mRemote;
      Proxy(android.os.IBinder remote)
      {
        mRemote = remote;
      }
      @Override public android.os.IBinder asBinder()
      {
        return mRemote;
      }
      public java.lang.String getInterfaceDescriptor()
      {
        return DESCRIPTOR;
      }
      /**
       * Demonstrates some basic types that you can use as parameters
       * and return values in AIDL.
       */
      @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeInt(anInt);
          _data.writeLong(aLong);
          _data.writeInt(((aBoolean)?(1):(0)));
          _data.writeFloat(aFloat);
          _data.writeDouble(aDouble);
          _data.writeString(aString);
          boolean _status = mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
          _reply.readException();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
      }
      /**
       * JRoomMeasurement函数中的参数皆为路径:
       * scenePath: 点云路径,文件类型为 pts、ptsen
       * compass_path: 方位文件路径———— dire.txt
       * Ruler_json: 用户设置的测量模式————ruler.json
       * cad_path: CAD文件路径
       * meshPath: 输出mesh.obj相关文件的路径
       * jsonPath:output.json输出路径
       */
      // no Blueprint
      @Override public boolean JRoomMeasurement(java.lang.String scenePath, java.lang.String compass_path, java.lang.String Ruler_json, java.lang.String cad_path, java.lang.String meshPath, java.lang.String jsonPath) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        boolean _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeString(scenePath);
          _data.writeString(compass_path);
          _data.writeString(Ruler_json);
          _data.writeString(cad_path);
          _data.writeString(meshPath);
          _data.writeString(jsonPath);
          boolean _status = mRemote.transact(Stub.TRANSACTION_JRoomMeasurement, _data, _reply, 0);
          _reply.readException();
          _result = (0!=_reply.readInt());
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
      @Override public boolean JRoomMeasurementFactory(java.lang.String scenePath, java.lang.String compass_path, java.lang.String cad_path, java.lang.String meshPath, java.lang.String jsonPath) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        boolean _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeString(scenePath);
          _data.writeString(compass_path);
          _data.writeString(cad_path);
          _data.writeString(meshPath);
          _data.writeString(jsonPath);
          boolean _status = mRemote.transact(Stub.TRANSACTION_JRoomMeasurementFactory, _data, _reply, 0);
          _reply.readException();
          _result = (0!=_reply.readInt());
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
      /**
       * The arguements of the API JScanMatch:
       * "-d",  ------- drawPath
       * "-x",  ------- xmlPath
       * "-s",  ------- stage
       * "-a",  ------- stationId
       * "-pm", ------- preMatchPath
       * "-im", ------- cadId
       * "-is", ------- xmlId
       * "-m",  ------- resultPath
       */
      // Own Blueprint
      /**
       * The arguements of the API ParseRoomScene
       * scene_path,      // 点云文件路径
       * compass_path,    // 方位文件路径
       * ruler_json,      // 测量规则配置文件
       * mesh_path,       // 网格输出路径
       * contour_xml      // 房间轮廓输出路径,输出为XML格式文件
       */
      @Override public void ParseRoomScene(java.lang.String scenePath, java.lang.String compass_path, java.lang.String ruler_json, java.lang.String meshPath, java.lang.String contour_xml) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeString(scenePath);
          _data.writeString(compass_path);
          _data.writeString(ruler_json);
          _data.writeString(meshPath);
          _data.writeString(contour_xml);
          boolean _status = mRemote.transact(Stub.TRANSACTION_ParseRoomScene, _data, _reply, 0);
          _reply.readException();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
      }
      @Override public boolean RoomMeasurementAndSaveData(java.lang.String jsonPath) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        boolean _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeString(jsonPath);
          boolean _status = mRemote.transact(Stub.TRANSACTION_RoomMeasurementAndSaveData, _data, _reply, 0);
          _reply.readException();
          _result = (0!=_reply.readInt());
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
      @Override public boolean JRoomMeasurementWithBluePrint(java.lang.String scenePath, java.lang.String compass_path, java.lang.String ruler_json, java.lang.String meshPath, java.lang.String contour_xml, java.lang.String drawPath, java.lang.String xmlPath, java.lang.String stage, java.lang.String stationId, java.lang.String preMatchPath, java.lang.String cadId, java.lang.String xmlId, java.lang.String matchResult, java.lang.String jsonPath) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        boolean _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeString(scenePath);
          _data.writeString(compass_path);
          _data.writeString(ruler_json);
          _data.writeString(meshPath);
          _data.writeString(contour_xml);
          _data.writeString(drawPath);
          _data.writeString(xmlPath);
          _data.writeString(stage);
          _data.writeString(stationId);
          _data.writeString(preMatchPath);
          _data.writeString(cadId);
          _data.writeString(xmlId);
          _data.writeString(matchResult);
          _data.writeString(jsonPath);
          boolean _status = mRemote.transact(Stub.TRANSACTION_JRoomMeasurementWithBluePrint, _data, _reply, 0);
          _reply.readException();
          _result = (0!=_reply.readInt());
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
    }
    static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_JRoomMeasurement = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    static final int TRANSACTION_JRoomMeasurementFactory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
    static final int TRANSACTION_ParseRoomScene = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
    static final int TRANSACTION_RoomMeasurementAndSaveData = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
    static final int TRANSACTION_JRoomMeasurementWithBluePrint = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
  }
  public static final java.lang.String DESCRIPTOR = "com.unre.ucl360.measurementservice.RMtAidlInterface";
  /**
   * Demonstrates some basic types that you can use as parameters
   * and return values in AIDL.
   */
  public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;
  /**
   * JRoomMeasurement函数中的参数皆为路径:
   * scenePath: 点云路径,文件类型为 pts、ptsen
   * compass_path: 方位文件路径———— dire.txt
   * Ruler_json: 用户设置的测量模式————ruler.json
   * cad_path: CAD文件路径
   * meshPath: 输出mesh.obj相关文件的路径
   * jsonPath:output.json输出路径
   */
  // no Blueprint
  public boolean JRoomMeasurement(java.lang.String scenePath, java.lang.String compass_path, java.lang.String Ruler_json, java.lang.String cad_path, java.lang.String meshPath, java.lang.String jsonPath) throws android.os.RemoteException;
  public boolean JRoomMeasurementFactory(java.lang.String scenePath, java.lang.String compass_path, java.lang.String cad_path, java.lang.String meshPath, java.lang.String jsonPath) throws android.os.RemoteException;
  /**
   * The arguements of the API JScanMatch:
   * "-d",  ------- drawPath
   * "-x",  ------- xmlPath
   * "-s",  ------- stage
   * "-a",  ------- stationId
   * "-pm", ------- preMatchPath
   * "-im", ------- cadId
   * "-is", ------- xmlId
   * "-m",  ------- resultPath
   */
  // Own Blueprint
  /**
   * The arguements of the API ParseRoomScene
   * scene_path,      // 点云文件路径
   * compass_path,    // 方位文件路径
   * ruler_json,      // 测量规则配置文件
   * mesh_path,       // 网格输出路径
   * contour_xml      // 房间轮廓输出路径,输出为XML格式文件
   */
  public void ParseRoomScene(java.lang.String scenePath, java.lang.String compass_path, java.lang.String ruler_json, java.lang.String meshPath, java.lang.String contour_xml) throws android.os.RemoteException;
  public boolean RoomMeasurementAndSaveData(java.lang.String jsonPath) throws android.os.RemoteException;
  public boolean JRoomMeasurementWithBluePrint(java.lang.String scenePath, java.lang.String compass_path, java.lang.String ruler_json, java.lang.String meshPath, java.lang.String contour_xml, java.lang.String drawPath, java.lang.String xmlPath, java.lang.String stage, java.lang.String stationId, java.lang.String preMatchPath, java.lang.String cadId, java.lang.String xmlId, java.lang.String matchResult, java.lang.String jsonPath) throws android.os.RemoteException;
}


网站公告

今日签到

点亮在社区的每一天
去签到