Back on AngelScript integration after having other projects running ...
Well, I've got a request or question :
Working with 1.9.0 WIP 4 (I will as soon as I can integrate 1.9.2) I am having troubles with the '=' operator.
I am using a class (that I have grabbed from the net) that is using CString.
Peharps you don't know about CString, it's an MFC string class that is using reference counting for not duplicating strings but rather having reference counting.
So, when you're making csTest1 = csTest2 , the CString = operator is called (MFC/SRC/STRCORE.CPP) :
const CString& CString::operator=(const CString& stringSrc)
{
if (m_pchData != stringSrc.m_pchData)
{
if ((GetData()->nRefs < 0 && GetData() != _afxDataNil) ||
stringSrc.GetData()->nRefs < 0)
{
// actual copy necessary since one of the strings is locked
AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);
}
else
{
// can just copy references around
Release();
ASSERT(stringSrc.GetData() != _afxDataNil);
m_pchData = stringSrc.m_pchData;
InterlockedIncrement(&GetData()->nRefs);
}
}
return *this;
}
As you can see, the '=' operator use InterlockedIncrement to not duplicate the real string but rather increment a reference count.
Ok, this is just to explain what's going on with AS.
I have referenced a class like this :
in_pAsEngine->RegisterObjectType("CSMTPAddress", sizeof(CSMTPAddress), asOBJ_CLASS);
in_pAsEngine->RegisterObjectBehaviour("CSMTPAddress", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(CSMTPAddress_Constructor), asCALL_CDECL_OBJLAST);
in_pAsEngine->RegisterObjectBehaviour("CSMTPAddress", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(CSMTPAddress_Destructor), asCALL_CDECL_OBJLAST);
in_pAsEngine->RegisterObjectMethod("CSMTPAddress", "CString GetRegularFormat(int bEncode, const CString& sCharset)",asMETHOD(CSMTPAddress,GetRegularFormat), asCALL_THISCALL);
in_pAsEngine->RegisterObjectMethod("CSMTPAddress", "void SetNameAndAdress(bstr sFriendly, bstr sAddress)",asMETHOD(CSMTPAddress,SetNameAndAdress), asCALL_THISCALL);
in_pAsEngine->RegisterObjectProperty("CSMTPAddress", "CString m_sEmailAddress", offsetof(CSMTPAddress, m_sEmailAddress));
in_pAsEngine->RegisterObjectProperty("CSMTPAddress", "CString m_sFriendlyName", offsetof(CSMTPAddress, m_sFriendlyName));
As you can see, there is NO asBEHAVE_ASSIGNMENT behaviour declared.
Now, this is the script :
CSMTPMessage msgSMTP;
CString csText;
CSMTPBodyPart csBodyPart;
CPJNSMTPConnection smtpCnx;
CSMTPAddress adrTo, adrFrom;
adrTo.SetNameAndAdress("zorba le grec", "donotemail@me.fr");
adrFrom.SetNameAndAdress("garou le hibou", "donotsend@hotmail.com");
csText = "Bonjour d'AngelScript";
csBodyPart.SetTitle(csText);
csText = "BodyPart\nvia angelscript\net\nSMTP PJ Naughter";
csBodyPart.SetText(csText);
msgSMTP.AddRecipient(adrTo, 0);
msgSMTP.m_From = adrFrom;
msgSMTP.m_Priority = 0;
msgSMTP.AddBodyPart(csBodyPart);
if (smtpCnx.Connect("smtp.wanadoo.fr", 0, "", "", 25, "") == 1) {
smtpCnx.SendMessage(msgSMTP);
smtpCnx.Disconnect(1);
}
This code is well compiled and not so well executed.
You can notice the :
msgSMTP.m_From = adrFrom;
The '=' operator is working but there is not '=' operator behaviour defined !
So, I don't know what AS is doing but the crash come at the msgSMTP destruction because, the CString that is member of CSMTPMessage is deleted and there is corrupted data in it.
How did I solve the pb ?
Simply in referencing the '=' operator behaviour that way :
CSMTPAddress *asCSMTPAddressCopy(const CSMTPAddress *src, CSMTPAddress *dst)
{
(*dst) = (*src);
return dst;
}
...
in_pAsEngine->RegisterObjectBehaviour("CSMTPAddress", asBEHAVE_ASSIGNMENT, "CSMTPAddress &f(const CSMTPAddress &)", asFUNCTION(asCSMTPAddressCopy), asCALL_CDECL_OBJLAST);
So, my request would be this one :
Is this a normal feature of AS to have a default '=' operator ?
If Yes, could it become No because it can cause some troubles on some referenced classes.
If No, I think that you can fire a bug event !
Regards,
AbrKen.