Archicad C++ API
About Archicad add-on development using the C++ API.

The access violation when create material attribute

Anonymous
Not applicable
Hi.
The access violation error occuers when I create a material attribute.
my code is

API_AttrTypeID typeID = API_MaterialID;
API_Attribute		attrib;
	API_AttributeDefExt	defs;
	BNZeroMemory(&attrib, sizeof(API_Attribute));
attrib.header.typeID = typeID;
	strcpy(attrib.header.name, u8"玻璃 - 蓝色");
	err = ACAPI_Attribute_Get(&attrib);
	if (err == NoError) {
		err = ACAPI_Attribute_GetDefExt(typeID, attrib.header.index, &defs);
		if (err == APIERR_BADID) {
			BNZeroMemory(&defs, sizeof(API_AttributeDefExt));
			err = NoError;
		}
		//能见度100
		attrib.material.transpPc = 100;
		if (err == NoError) {
			strcpy(attrib.header.name, name.ToCStr().Get());
			err = ACAPI_Attribute_Create(&attrib,nullptr);
		}
		ACAPI_DisposeAttrDefsHdlsExt(&defs);
	}
5 REPLIES 5
Akos Somorjai
Graphisoft
Graphisoft
Hi,

Please use attrib.header.uniStringNamePtr Instead of attrib.header.name, because the .name is limited in length:
GS::UniString attrName (u8"玻璃 - 蓝色");
attrib.header.uniStringNamePtr = &attrName;
and instead of strcpy(attrib.header.name, name.ToCStr().Get()); use:
attrib.header.uniStringNamePtr = &name;
Best, Akos
Anonymous
Not applicable
Akos wrote:
Hi,

Please use attrib.header.uniStringNamePtr Instead of attrib.header.name, because the .name is limited in length:
GS::UniString attrName (u8"玻璃 - 蓝色");
attrib.header.uniStringNamePtr = &attrName;
and instead of strcpy(attrib.header.name, name.ToCStr().Get()); use:
attrib.header.uniStringNamePtr = &name;
Best, Akos
According to your method,the problem also occuers.
Ralph Wessel
Mentor
DevJeer wrote:
Akos wrote:
Hi,

Please use attrib.header.uniStringNamePtr Instead of attrib.header.name, because the .name is limited in length:
GS::UniString attrName (u8"玻璃 - 蓝色");
attrib.header.uniStringNamePtr = &attrName;
and instead of strcpy(attrib.header.name, name.ToCStr().Get()); use:
attrib.header.uniStringNamePtr = &name;
Best, Akos
According to your method,the problem also occuers.
I notice you've changed the call for creating the material to ACAPI_Attribute_CreateExt and you're passing a API_AttributeDefExt parameter. Materials don't use API_AttributeDefExt, so perhaps you should be passing just nullptr for that parameter?
Ralph Wessel BArch
Software Engineer Speckle Systems
Akos Somorjai
Graphisoft
Graphisoft
Hi,

Here's the code that works for me:
{
	GS::UniString name (u8"能见度100");

	API_AttrTypeID typeID = API_MaterialID;
	API_Attribute attrib = {};
	API_AttributeDefExt defs = {};
	GSErrCode err = NoError;

	GS::UniString attrName(u8"玻璃 - 蓝色");
	attrib.header.typeID = typeID;
	attrib.header.uniStringNamePtr = &attrName;
	//strcpy(attrib.header.name, u8"玻璃 - 蓝色");
	err = ACAPI_Attribute_Get (&attrib);
	if (err == NoError)
	{
		err = ACAPI_Attribute_GetDefExt (typeID, attrib.header.index, &defs);
		if (err == APIERR_BADID)
		{
			err = NoError;
		}
		//能见度100
		attrib.material.transpPc = 100;
		if (err == NoError)
		{
			attrib.header.uniStringNamePtr = &name;
			//strcpy(attrib.header.name, name.ToCStr().Get());
			err = ACAPI_Attribute_CreateExt (&attrib, &defs);
		}
	}
	ACAPI_DisposeAttrDefsHdlsExt(&defs);

	return;
}
I think the main problem was calling ACAPI_Attribute_Create instead of ACAPI_Attribute_CreateExt.

Best, Akos
Anonymous
Not applicable
Thanks.
The code don't work for me.

API_AttrTypeID typeID = API_MaterialID;
GSErrCode err = NoError;
API_Attribute attrib={};
API_AttributeDefExt defs={};

attrib.header.typeID = typeID;
//strcpy(attrib.header.name, u8"玻璃 - 蓝色");
GS::UniString materialName(u8"玻璃 - 蓝色");
attrib.header.uniStringNamePtr = &materialName;
err = ACAPI_Attribute_Get(&attrib);
if (err == NoError) {
    err = ACAPI_Attribute_GetDefExt(typeID, attrib.header.index, &defs);
    if (err == APIERR_BADID) {
        BNZeroMemory( & defs, sizeof(API_AttributeDefExt));
        err = NoError;
    }
    //能见度100
    attrib.material.transpPc = 100;
    if (err == NoError) {
        //strcpy(attrib.header.name, name.ToCStr().Get());
        GS::UniString attrName(u8"界线");
        attrib.header.uniStringNamePtr = &attrName;
        err = ACAPI_Attribute_CreateExt( &attrib, &defs);
    }
    ACAPI_DisposeAttrDefsHdlsExt(&defs);
}
The same problem also occurs.
The version of Archicad is 22 and the version of vs is 2015.