Developer forum
cancel
Showing results for 
Search instead for 
Did you mean: 

Selecting SEO operators

Anonymous
Not applicable
Hi,

I'm trying to find and select all SEO operators. I'm fairly new to C++ and was wondering why this code doesn't work? The commented line crashes ArchiCAD and I'm not sure why.
GS::GSErrCode err = NoError;
GS::Array<API_Guid> allElements;
		
ACAPI_Element_GetElemList(API_ZombieElemID, &allElements);

for (const API_Guid &guid : allElements) {

	GS::Array<GS::UniString> guidStrings;
	API_Guid **guid_Operators = nullptr;
	Int32 nLinks;
	err = ACAPI_Element_SolidLink_GetOperators(guid, &guid_Operators, &nLinks);

	BMhFree(reinterpret_cast<GSHandle> (guid_Operators));

	if (err != NoError)
		continue;

	GS::Guid nGuid = APIGuid2GSGuid (**guid_Operators); //crashes ArchiCAD

	GS::UniString guidString = nGuid.ToUniString();
	guidStrings.Push(guidString);

	const USize count = guidStrings.GetSize();

	API_Neig** neigs = (API_Neig**)(BMAllocateHandle(count * sizeof(API_Neig), ALLOCATE_CLEAR, 0));
	for (UIndex i = 0; i < count; ++i) {
		(*neigs).guid = APIGuidFromString(guidStrings.ToCStr().Get());
	}

	ACAPI_Element_Select(neigs, count, true);
	BMKillHandle(reinterpret_cast<GSHandle*> (&neigs));

}

If anyone could help that would be great.

Thanks
3 REPLIES 3

Hello,

Can you explain here where do you put these C++ lines to be sure that everyone is able to understand ?
Christophe - FRANCE
Archicad Designer and Teacher
Archicad 15 to 24 FRA FULL
OS 11 Big Sur

"Quality is never an accident; it's always the result of an intelligent effort " - John Ruskin

Ralph Wessel
Mentor
It's because the data you want to inspect is destroyed in this line:
BMhFree(reinterpret_cast<GSHandle> (guid_Operators));
That instruction releases the memory used by that variable, so the data is no longer safe or meaningful, hence it crashes when you try to reference it in the following line:
GS::Guid nGuid = APIGuid2GSGuid (**guid_Operators);
Don't release the allocated memory until you're finished with it.
Ralph Wessel BArch

Anonymous
Not applicable
Thanks for the replies. Currently I'm using this code in a ButtonClicked function in a modal dialog box. I've managed to fix it so that it functions as required.
void Dialog::ButtonClicked(const DG::ButtonClickEvent& ev) {

	GS::GSErrCode err = NoError;
	GS::Array<API_Guid>	allElements;

	if (ev.GetSource() == &button)
		Text.SetText(CalculateCount());
	else if (ev.GetSource() == &sButton) {

		if (sButton.GetText() == "Select")

			Text.SetText("Please use the drop down menu to choose\nwhat to select");

		else if (sButton.GetText() == sButton.GetItemText(1)) {

			Text.SetText("Close this dialog to finish selection");

			ACAPI_Element_GetElemList(API_ZombieElemID, &allElements);

			for (const API_Guid& guid : allElements) {

				GS::Array<GS::UniString> guidStrings;
				API_Guid** guid_Operators = nullptr;
				Int32 nLinks = 0;
				err = ACAPI_Element_SolidLink_GetOperators(guid, &guid_Operators, &nLinks);

				if (err != NoError) {
					continue;
				}

				API_Neig** neigs = (API_Neig * *)(BMAllocateHandle(nLinks * sizeof(API_Neig), ALLOCATE_CLEAR, 0));
				for (int i = 0; i < nLinks; i++) {
					(*neigs).guid = guid_Operators[0];
				}

				ACAPI_Element_Select(neigs, nLinks, true);
				BMKillHandle(reinterpret_cast<GSHandle*> (&neigs));
				BMhFree(reinterpret_cast<GSHandle> (guid_Operators));

			}
		}
		else if (sButton.GetText() == sButton.GetItemText(2)) {

			Text.SetText("Close this dialog to finish selection");

			ACAPI_Element_GetElemList(API_ZombieElemID, &allElements);

			for (const API_Guid& guid : allElements) {

				GS::Array<GS::UniString> guidStrings;
				API_Guid** guid_Targets = nullptr;
				Int32 nLinks = 0;
				err = ACAPI_Element_SolidLink_GetTargets(guid, &guid_Targets, &nLinks);

				if (err != NoError) {
					continue;
				}

				API_Neig** neigs = (API_Neig * *)(BMAllocateHandle(nLinks * sizeof(API_Neig), ALLOCATE_CLEAR, 0));
				for (int i = 0; i < nLinks; i++) {
					(*neigs).guid = guid_Targets[0];
				}

				ACAPI_Element_Select(neigs, nLinks, true);
				BMKillHandle(reinterpret_cast<GSHandle*> (&neigs));
				BMhFree(reinterpret_cast<GSHandle> (guid_Targets));

			}
		}
	}
}

Cheers.

Still looking?

Browse more topics

Back to forum

See latest solutions

Accepted solutions

Start a new discussion!