Instantiate in C++, pass to C# - Manage memory and prevent leaks

Hello all,

I have been working with a project that is basically a plugin in C# that uses a lot of unmanaged code written in C++. For others that end up hitting this question, you can google the Moose project available in GitHub from @dale.

I have some questions when having this more advanced use case, that I will separate in different topics so that it would stay in the internet for our grandkid’s use.

1- Say my C# plugin calls a C++ function that will return a more complex opennurbs object (ON_Mesh, ON_Brep, etc.). What is the recommended way to instanciate this object in the C++ code?
Should I use a simple new, or should I use one of the functions that are available in the opennurbs_memory.h [ ON_DECL void* onmalloc_forever( size_t ); ON_DECL void* onmalloc( size_t ); ON_DECL void* oncalloc( size_t, size_t ) ];
? If yes, we definately need references to those functions.

2- Now, say that the C++ code needs to free the memory of an opennurbs object. Can we trust that calling the ON_.Destroy() will free the memory of the object and of all of its inner stuff?

In technical terms, is this C++ code the recommended way?


extern "C" __declspec(dllexport) ON_Mesh* CppMeshBuilder()
{
	ON_Mesh* outOnMesh = NULL;
	try
	{
		int expectedFaces = 1000; 
		int expectedVertices = 5000;

		// ********** QUESTION: Is NEW appropriate?
		// Instanciates with NEW
		outOnMesh = new ON_Mesh(expectedFaces, expectedVertices, false, false);

		// Saves the vertices
		for (size_t i = 0; i < expectedVertices; i++)
		{
			ON_3fPoint p(x,y,z); // x,y,z placeholders
			outOnMesh->m_V.Append(p);
		}

		// Saves the faces
		for (size_t i = 0; i < expectedFaces; i++)
		{
			ON_MeshFace face = ON_MeshFace::UnsetMeshFace;
			
			face.vi[0] = i0; // placeholder
			face.vi[1] = i1; // placeholder
			face.vi[2] = i2; // placeholder
			face.vi[3] = face.vi[2]; // triangular

			outOnMesh->m_F.Append(face);
		}

		// As seen in the OpenNurbs implementation, this will do all culls together
		outOnMesh->CullDegenerates();
	}
	catch (const std::exception& ex)
	{
		if (outOnMesh != NULL)
		{
			// ********** QUESTION: Does destroy suffice?
			outOnMesh->Destroy();
		}

		return NULL;
	}
}

@dale Perhaps adding an example like this to the Moose project would make sense?

Yes.

I’ve added a sample to the Moose solution.

– Dale

1 Like