OCAF sample

Hi, I've tried to test ocafsample, but Open/Save doesn't work properly. During saving looks to save but during opening it doesn't work. Probably is saving but I'm not sure.

Other problem is that Ocaf documentation talks about constraint between entities and specobjects, but there is nothing inside the ocafsample.Someone as information about it?

Best regards Carlo

t-haller's picture

Hi Carlo,

The effect you describe is only found with the Windows version of OCC 3.1. It is locale dependend. Have a look into the file saved. You will probably find real numbers printed with a "," instead of a ".". The application reading such a file produces an internal error (which is not passed through to the user interface) and stops reading the file.

This problem should be solved with version 4.0.

Best regards

Thomas

Christophe Thabaud's picture

The troubles come from some bad memory allocation. This can be easily fixed.

In following files: StorageSchema.cxx - ICreationDate(), PCDM_StorageDriver.cxx - Write(...), and PCDM_RetrievalDriver - Read(...)

Replace: :: // on sauvegarde l'ancien LC_NUMERIC :: char *oldnum = setlocale(LC_NUMERIC, NULL) with: :: // on sauvegarde l'ancien LC_NUMERIC :: char oldnum[1024]; :: strcpy( oldnum, setlocale(LC_NUMERIC, NULL));

The bug comes from different C Runtime Env in dlls : locale is set to "C" in PCDM_StorageDriver Write(...), for instance, but a call to another dll (containing schema) is performed assuming that locale will be "C" too. Actually, the locale is "C" in both dlls but only at the first call : trying to restore the locale stored in oldnum (without memory allocation) will result in setting locale to OS default locale ! So if you replace lines of code above, you will not get into the following trouble:

------------------------------ PCDM_StorageDriver Write() :

// Locale here is usually "C" but could // be anything

char *oldnum = setlocale( LC_NUMERIC, NULL); // here oldnum = "C" in many case // Then ensure locale is "C" for storing setlocale( LC_NUMERIC, "C");

... some code performing anything you want ... ... with a call to another dll to write physical ... file

// Restoring locale before call // oldnum can be anything ... setlocale( LC_NUMERIC, oldnum); // ... so this call results in setting locale to // OS default locale // Here default locale decimal point is OS one // and call to any methods assuming that setting // locale just before call to "C" will be enough // will result in bad behaviour --------------------------------

Restoring locale to anything would not be too damageable for file saving if we do not find this mechanism in storage schema in ICreationDate : any further call to methods in this dll will result in bad decimal point ! And the schema is responsible for writing reals !

So first save ok : '.' Second save bad : ',' You can test it easily.

Thanks for commenting these remarks. Christophe Thabaud

PS: However, setlocale(LC_NUMERIC, "C") does not imply that decimal point will be '.'; it can actually be change easily by mistake anywhere else in code...