Compiler errors with Visual Studio 2015 on functions acdbRToS + acedFindFile

Hi all readers,
I'm porting my ARx-applications from AutoCAD to BricsCAD V18.
I have made some progress, but at the moment I'm struggling with the 2 above mentioned functions.

They compile fine when i target AutoCAD, but fail with the target BricsCAD V18

These errors are reported in Visual Studio 2015
1>....\arm-src\rmold-commands.cpp(1490): error C2660: 'acdbRToS': Funktion akzeptiert keine 4 Argumente
1>....\arm-src\rmold - commands.cpp(1524) : error C2660 : 'acedFindFile' : Funktion akzeptiert keine 2 Argumente

Checking the function definitions clearly indicates the number of arguments are 4 and 2, the argument types also match the definition.
At this point i have no clue how to go on...

Can someone point me to a possible workaround or any step to get over these erros?

Many thanks in advance.

Kind regards,
Richard

In case there's anyone who likes to try it out at his place, here's a small demo function

// Test for compiler problem on functions acdbRToS + acedFindFile
void testcompiler()
{
//
// Compiler-Error on acdbRToS
//
int iDecs = 3;
ACHAR* sRTOS;
Acad::ErrorStatus allocstat = acutNewString(sRTOS, 512);
if (allocstat != Acad::eOk) acedAlert(ACRX_T("Memory error!"));
//
ads_real dblVal = 2.789456123;
int iPrec = 2;
int retv = acdbRToS(dblVal, iPrec, iDecs, sRTOS);
//
acutDelString(sRTOS);
//
//
//
//
//
//
// Compiler-Error on acedFindFile
//
ACHAR* testpath;
Acad::ErrorStatus allocstat = acutNewString(testpath, 512);
if (allocstat != Acad::eOk) acedAlert(ACRX_T("Memory error!"));
//
int ffstat = acedFindFile((ACRX_T("C:\Temp\test.txt")), testpath);
//
//
acutDelString(testpath);
//
return;
}

Comments

  • Hi Richard,

    You either need to provide a buffer length argument (good), or let the compiler determine buffer size (better):
    acdbRToS(dblVal, iPrec, iDecs, sRTOS, 512);
    or:
    ACHAR sRTOS[512] = _ACRX_T(""); acdbRToS(dblVal, iPrec, iDecs, sRTOS); //don't call acutDelString(sRTOS) any more

    Regards

  • Dear Richard,

    seems, your code was for an older ARX version ?

    Here are the actual ARX + BRX declarations :

    int acdbRToS ( ads_real val, int unit, int prec, ACHAR* str, size_t nBufLen );
    int acedFindFile ( const ACHAR * fname, ACHAR* result, size_t nBufLen );

    hope this explains ?
    many greetings !

  • Many thanks Owen and Torsten for your tips and infos.

    It's right, the sources are from AutoCAD 2010.
    So there might be more issues related to porting for a recent ARx and BRx version.

    In the meantime i have seen similar problems to acedGetstring and some other library functions.
    Hopefully, i will overcome these problems as well.

    If not, i will soon be back at this forum to ask additional questions.

    Many thanks again and all my best wishes for the upcoming new year 2018...

    Richard

  • Dear Richard,

    good to hear ... as far as I have seen, ARX extended a number of "old-style" ADS/ aced/acdb/acut global functions with an additional "string-length" argument ... just to prevent buffer overflows;
    besides those changes, the ADS/global functions were not really changed at all :-)

    many greetings & all the best for 2018 :-)
    Torsten

  • @Owen Wengerd said:
    Hi Richard,

    You either need to provide a buffer length argument (good), or let the compiler determine buffer size (better):
    acdbRToS(dblVal, iPrec, iDecs, sRTOS, 512);
    or:
    ACHAR sRTOS[512] = _ACRX_T(""); acdbRToS(dblVal, iPrec, iDecs, sRTOS); //don't call acutDelString(sRTOS) any more

    Regards

    Hi Owen,
    i tried to follow your advice and to remove all occurences of acutDelString() in my code.

    During this stage I've realized that there are functions where the usage of acutDelString() is required.
    For example, the AcDbEntity->layer() function returns an ACHAR* pointer.
    The ARx 2018 documentation tells about the returned buffer:
    ->
    This function returns a copy of the name string in the AcDbLayerTableRecord object referenced by the entity.
    The calling application is responsible for deallocating the memory used by the returned string. The acutDelString() function is recommended.
    <-

    Is this a exception from your general rule?

    It would be nice to have some additional information on this subject.
    If you can give any clarification. I'm looking forward to read it.

    Kind regards,
    Richard

  • Hi Richard, the only general rule is that memory allocated on the heap must be deallocated again (e.g. via acutDelString). I gave you an example of allocating memory on the stack:
    ACHAR sRTOS[512] = _ACRX_T("");

    Since it's allocated on the stack, it can't be deallocated. It will just get overwritten after the function returns. I hope that clarifies.

  • Hi Owen,
    many thanks for your explanation.
    I'm aware of the different behaviour when memory is allocated from the heap or stack.
    it was just not sure about the allocation state in the named functions.
    I do not see if they allocate their memory.
    And the next question for me was: are all of the rules and restrictions in Object ARx the same with Brx?
    Or are there differences?
    For the moment, i think it's clear for me to go on with AcutDelString() on memory from internal runtime functions like ->layer(), ->name() or such.
    Regards,
    Richard

  • Hi Richard,

    Off the top of my head, I think you could go with this (these are just standard for any API, nothing particular about ARX or BRX):

    1. If you allocated it, you own it and are responsible for deallocating it.
    2. If an API allocated it and it returned it as a const pointer, then the allocated memory is not your responsibility, but don't store it because you won't know when the memory is deallocated.
    3. If an API allocated it and returned it as a non-const pointer, you take over ownership of it and are responsible for deallocating it.

    Note that there are several signatures of AcDbSymbolTableRecord::getName(). If you don't need a long term copy of the name, make sure you call the const ACHAR* version, otherwise you'll get a newly allocated copy that you have to deallocate.

    Regards

This discussion has been closed.