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

Converting addon from xcode to visual studio

julienK
Advocate

Hi,

 

My office decided to switch from mac to pc so I have to recompile all my addons.

 

With a few minor tweaks i got my first one to compile in visual studio but can't load it in Archicad.

the extension manager says 'this file is an old addon that can't be used in this Archicad version'

 

Its not an MDID error, and the same happens in demo and normal mode. The grc files compile without errors.

the only error i get in the log is:

 

ACAP_STAT.lib(ACAPlib_.obj) : warning LNK4099: PDB 'API_c.pdb' could not be found with 'ACAP_STAT.lib(ACAPlib_.obj)' or in 'D:\Graphisoft API\00 Win64\API Development Kit 25.3002\Examples\JK_Test-3\Build\x64\Release\API_c.pdb' ; l'objet sera lié sans informations de débogage

 

but this error appears also with the example addons.

 

I spent the whole weekend trying to find a solution but I'm stuck. I looked everywhere in the visual studio properties for a definition of the target Archicad version but couldn't find anything.

 

I'm using Archicad 25 4013, visual studio 2019 142 and I have the latest dev kit installed  25.3002

 

Any help would be much appriciated.

1 ACCEPTED SOLUTION

Accepted Solutions
Solution
Akos Somorjai
Graphisoft
Graphisoft

Hi Julien,

 

I have just sent the corrected add-on back to you. The reason why you add-on was not loading that a runtime exception was thrown while loading the .apx.

 

Exception thrown: read access violation.
this->**content** was nullptr.

 

[Inline Frame] GSRoot.dll!GS::TSRefCounter::operator>(int) Line 105 C++
[Inline Frame] GSRoot.dll!GS::UniString::AboutToModify(unsigned int) Line 950 C++
GSRoot.dll!GS::UniString::Set(const char * chars, unsigned int logicalLength, unsigned int physicalLength, GSCharCode charCode) Line 707 C++
GSRoot.dll!GS::UniString::operator=(const char * cStr) Line 433 C++
> DG_Test.apx!`dynamic initializer for 'typoLims''() Line 74 C++
[External Code]
GSRoot.dll!GS::LoadModule(const wchar_t * modulePath) Line 30 C++
GSUtils.dll!IOUtil::ModuleFile::Load() Line 1267 C++
Archicad.exe!APIModule::Load() Line 115 C++

...

 

And the reason behind that is that you use a GS::UniString in a global variable; it took a while to figure that out:

 

In your header file you declared a struct like this:

 

typedef struct {

...

    GS::UniString  T1;

...

typoLimits;

 

And in your .cpp file you initialized a global variable:

 

typoLimits typoLims = {

...

    typoLims.T1 = "T1", 

...

};

 

This doesn't work well, as GSRoot is not really loaded for your add-on at DLL initialization time.

 

Best, Akos

View solution in original post

6 REPLIES 6
Akos Somorjai
Graphisoft
Graphisoft

Hi Julien,

 

Couple of things come into my mind:

- check if you are compiling a 64-bit version of the add-on

- even though you have a valid MDID, open your built add-on in Visual Studio as Resources, and check if the MDID resource is really in the binary file

 

The warning you showed is not a problem, it doesn't effect the validity of the add-on.

 

Best, Akos

Hi Akos,

 

I definitely compiled  in x64.

 

All I could find in the mdid folder of the binary is:

mdidbin.jpg

Hi Julien,

 

This seems to be correct. Could you please send me (here, or mail it to asomorjai@graphisoft.com) your add-on? I'll check it here.

 

Best, Akos

Solution
Akos Somorjai
Graphisoft
Graphisoft

Hi Julien,

 

I have just sent the corrected add-on back to you. The reason why you add-on was not loading that a runtime exception was thrown while loading the .apx.

 

Exception thrown: read access violation.
this->**content** was nullptr.

 

[Inline Frame] GSRoot.dll!GS::TSRefCounter::operator>(int) Line 105 C++
[Inline Frame] GSRoot.dll!GS::UniString::AboutToModify(unsigned int) Line 950 C++
GSRoot.dll!GS::UniString::Set(const char * chars, unsigned int logicalLength, unsigned int physicalLength, GSCharCode charCode) Line 707 C++
GSRoot.dll!GS::UniString::operator=(const char * cStr) Line 433 C++
> DG_Test.apx!`dynamic initializer for 'typoLims''() Line 74 C++
[External Code]
GSRoot.dll!GS::LoadModule(const wchar_t * modulePath) Line 30 C++
GSUtils.dll!IOUtil::ModuleFile::Load() Line 1267 C++
Archicad.exe!APIModule::Load() Line 115 C++

...

 

And the reason behind that is that you use a GS::UniString in a global variable; it took a while to figure that out:

 

In your header file you declared a struct like this:

 

typedef struct {

...

    GS::UniString  T1;

...

typoLimits;

 

And in your .cpp file you initialized a global variable:

 

typoLimits typoLims = {

...

    typoLims.T1 = "T1", 

...

};

 

This doesn't work well, as GSRoot is not really loaded for your add-on at DLL initialization time.

 

Best, Akos

Thanks a lot Akos,

I don't know how I could have figured this out on my own.

that's actually the only bit of code I modified from xcode to visual studio. (adding the typolims before the "." in that struct for some reason xcode was happy with that but not visual studio. I think it has something to do with c++14.

 

I hope it all makes sense to me one day, right now its pretty much 'throw something at the wall and see if it sticks kind of approach'.

Yeah, that was a tough one, glad I could help 🙂

 

Feel free to ask next time, that's what we are here for 🙂

 

Have a nice day, Akos