Changing the Library folder in ARCHICAD12
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2009-02-04
07:53 AM
- last edited on
2024-09-09
10:54 AM
by
Doreena Deng
I want to change my project Libraries Folder in ArchiCAD 12.
I am using following function.
Void setupLibrariesForAC12()
{
API_LibrariesInfo libInfo;
memset(&libInfo, 0, sizeof(API_LibrariesInfo));
libInfo.nLib = 2;
libInfo.locations = (IO::Location**) BMAllocateHandle (libInfo.nLib * sizeof(IO::Location, ALLOCATE_CLEAR, 0);
libInfo.useSatellite = false;
new (*libInfo.locations) IO::Location (“C:\\Archicad12\\Archicad Library”);
new (*libInfo.locations + 1) IO::Location (“C:\\Archicad Development Library”);
ACAPI_Environment(APIEnv_SetLibrariesID, &libInfo, NULL);
(*libInfo.locations).~Location();
(*libInfo.locations + 1).~Location();
BMKillHandle(reinterpret_cast<GSHandle *> (&libInfo.locations));
}
But I am getting following errors
err LNK2001:unresolved external symbol “public: virtual class GS::ClassInfo * __thiscall GS::Object::GetClassInfoA(void)const “(?getClassInfoA@object@GS@@UBEPAVClassInfo@2@XZ)
fatal error LNK1120: 1 unresolved externals.
Please help me to solve these errors.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2009-02-04 04:01 PM
Ranga wrote:Does the problem go away if you write it like this (i.e. changing just part of your function)?
I want to change my project Libraries Folder in ArchiCAD 12.
I am using following function.
Void setupLibrariesForAC12()
...etc...
Please help me to solve these errors.
libInfo.locations = (IO::Location**) BMAllocateHandle (libInfo.nLib * sizeof(IO::Location, ALLOCATE_CLEAR, 0); libInfo.useSatellite = false; (*libInfo.locations)[0] = IO::Location(“C:\\Archicad12\\Archicad Library”); (*libInfo.locations)[1] = IO::Location(“C:\\Archicad Development Library”); ACAPI_Environment(APIEnv_SetLibrariesID, &libInfo, NULL); BMKillHandle(reinterpret_cast<GSHandle *> (&libInfo.locations));
Central Innovation

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2009-02-04 04:19 PM
Have you GSRootImp.LIB in your project ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2009-02-04 09:13 PM
Oleg wrote:Oleg,
Hi,
Have you GSRootImp.LIB in your project ?
What a good surprise to read you. It's a long time. I hope you are fine.
Your GDL and API programmer expertise is missing.
Kliment recently pointed out your "rxDuplicator" Add-On (AC8 & 9), among other jewels.
Years after, the similar tool on AC12, is a bit poor, in comparison.
May we expect from you a come back on AC-Talk?
Cheers,
Olivier
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2009-02-05 01:26 AM
It is working fine if i use
(*libInfo.locations)[0] = IO::Location("C:\\ArchiCAD 12\\ Archicad Library 12");
but in the run time it is failing
at line
(*libInfo.locations)[0].~Location();
i can't use the try and catch because it is saying "error C2712: Cannot use __try in functions that require object unwinding"
i don't know what to do. can you please help me ranga

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2009-02-05 05:54 AM
Olivier wrote:Hi Olivier and all, thanks for warm words. I am fine.
What a good surprise to read you. It's a long time. I hope you are fine.
Olivier
I occasionally read the Talk, but I have no time to participate absolutely.
( Also has almost forgotten English language in addition.

Good luck. I should disappear again.
PS: Ranga, I am sorry for personal messages in your thread.
Oleg

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2009-02-05 07:35 AM
(I am sorry my English)
I am not sure in following, just guessing.
Actually, it seems is a right way:
new (*libInfo.locations) IO::Location ("C:\\Archicad12\\Archicad Library");
new (*libInfo.locations + 1) IO::Location ("C:\\Archicad Development Library");
and then
(*libInfo.locations)->~Location();
(*libInfo.locations + 1)->~Location();
But looking at Location header (Location class), there is :
#if defined (DEBUVERS)
Int32* leakDetector;
#endif
So, sizeof of Location class is different in Debug and Release build.
And I think none of attemts will not work in Debug mode.
Try your code in Release mode. It may works.
I think only GS may explain this.
May be there is a way #undef DEBUVERS in your cpp source before #includes, but not sure.
Oleg
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2009-02-05 10:36 AM
Ranga wrote:That line is directly calling the object's destructor. In the GS example, this is used because they have used placement new in order to directly call the object's constructor and specify where the object is to be allocated. If you take out the placement new (which was my suggestion) you no longer need to call the destructor - it will fail if you do (which is what you are seeing). Either use the code exactly as I stated or use the GS example, but don't mix them.
Hi Ralph Wessel,
It is working fine if i use
(*libInfo.locations)[0] = IO::Location("C:\\ArchiCAD 12\\ Archicad Library 12");
but in the run time it is failing
at line
(*libInfo.locations)[0].~Location();
I would like someone from GS to comment on this, because I don't see an obvious reason for using placement new to allocate the object. Anyone?
Central Innovation

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2009-02-05 10:53 AM
I agree, GS should comment all of this.
My idea about destructor.
I think it is correct:
(*libInfo.locations)[0] = IO::Location("C:\\ArchiCAD 12\\ Archicad Library 12");
I guess, placement new used only to avoid copy. Just to optimize.
But I think, destructor needs anyway to avoid memory leak at kill handle.
(*libInfo.locations)[0].~Location();
And It is possible that will work for first member of array.
But I think if DEBUVERS is defined then next items of array like
(*libInfo.locations)[1] = IO::Location("C:\\ArchiCAD 12\\ Archicad Library 12");
will not work as copied at wrong place. But really it is correct, you are right.
Intresting stuff. But have no time to test.
Oleg
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2009-02-05 11:02 AM
Oleg wrote:The destructor call is only necessary if you have allocated the object with placement new. No memory will be leaked because it is has been allocated (and released) as a handle.
I guess, placement new used only to avoid copy. Just to optimize.
But I think, destructor needs anyway to avoid memory leak at kill handle.
(*libInfo.locations)[0].~Location();
There seems no reason to use placement new for allocation in this case. Yes, it is an 'optimisation', but completely pointless because this call would never be used in a context where optimal performance could make an appreciable difference.
Optimising where there is no benefit, especially where is the code becomes less readable or balancing calls like 'new' and 'delete' are necessary, is both wasteful and risky. I would like to know if there is some other reason why the GS example does this.
Central Innovation