2024-01-05 07:43 PM - last edited on 2024-09-17 11:29 AM by Doreena Deng
AC27 - - WIN10 - - VS2019
.
New Year greetings to all. I am migrating code from AC25 to AC27, and Visual Studio is giving me some pushback that I don't really understand. I might add that I am not the original author of this code. The working AC25 code is this:
#include <APIdefs_Elements.h>
//------------------------------------------------------
// Element driven events
//------------------------------------------------------
GSErrCode __ACENV_CALL NewElementEventHandler(const API_NotifyElementType *notifyElemType) // new element
{
GSErrCode err = NoError;
// Do nothing if the live audit is not enabled
if (!JHP::LiveAudit::GetInstance().Enabled())
return err;
if (notifyElemType->elemHead.typeID == API_DimensionID)
{
if (notifyElemType->notifID == -1)
JHP::LiveAudit::GetInstance().Observe(notifyElemType->elemHead.typeID, notifyElemType->elemHead.guid);
}
else
JHP::LiveAudit::GetInstance().Observe(notifyElemType->elemHead.typeID, notifyElemType->elemHead.guid);
...
Visual Studio is telling me: class "API_Elem_Head" has no member "typeID"
My research into this is:
Making the edit from .typeID to .type seems to work for the if condition [0], but is not happy when used in the .Observe arguments [1, 2].
Looking at the user defined LiveAudit class methods, I find
void Observe (API_ElemTypeID, API_Guid);
which surprises me, since this code is working in AC25 and GS documentation states that API_ElemTypeID has only been available since AC26.
Have I told enough of the story for someone to point me in the right direction so that I may solve this migration?
If not, let me know.
All the best,
Chris
2024-01-06 01:20 PM - edited 2024-01-06 01:28 PM
Prior to Archicad 26 the element type was represented by a single enum of type API_ElemTypeID. Starting from Archicad 26 the element type is represented as a struct named API_ElemType. It contains the same enum as before, but also contains other identification data (like API_Guid for identifying external elements, like the new MEP elements).
What can you do?
2024-01-09 05:13 PM - edited 2024-01-09 05:52 PM
@Viktor Kovacs - thanks for the info. I will rewrite code to use API_ElemType everywhere so we have a more future-proof implementation. That just makes sense.
But... if I am allowed to continue using the API_ElemTypeID enum from the API_ElemType struct, why would this be reading as an error now, without making any edits? Just curious...
Thanks for your continued support and insight,
Chris
2024-01-10 08:15 AM
The type field was earlier an enum, and is now a struct. If a function expects an enum than it won't compile. The other way will silently work because API_ElemType has a non-explicit one-parameter constructor with an enum value, so the compiler will construct the object automatically.
2024-01-11 12:12 AM - edited 2024-01-11 08:19 PM
@Viktor Kovacs - - thanks agian for the detailed explanation. I feel like this is basic stuff, but I don't know what I don't know. After your comments, I was able to correct all of these API_ElemTypeID vs. API_ElemType instances in my project in a matter of a few minutes. Also - a few other edits to respond to changes in the API since AC25.
I have another struggle in the same project migration with something I wonder might be related. All of the coding seems to be agreeable, but I am receiving LNK2019 errors [unresolved external symbol 'symbol' referenced in function 'function']. 29 of them to be exact and all related to methods in a couple of different classes.
Building Custom Rule G:/dev/v27/JHP_Audit/CMakeLists.txt
APICommon.c
JHP_Audit.cpp
Generating Code...
G:\dev\v27\JHP_Audit\out\build\x64-Release\JHP_Audit.obj : error LNK2019: unresolved external symbol "public: static bool __cdecl JHP::LiveAudit::HasInstance(void)" (?HasInstance@LiveAudit@JHP@@SA_NXZ) referenced in function "int __cdecl ProjectEventHandler(enum API_NotifyEventID,int)" (?ProjectEventHandler@@YAHW4API_NotifyEventID@@H@Z)
G:\dev\v27\JHP_Audit\out\build\x64-Release\JHP_Audit.obj : error LNK2019: unresolved external symbol "public: static class JHP::LiveAudit & __cdecl JHP::LiveAudit::GetInstance(void)" (?GetInstance@LiveAudit@JHP@@SAAEAV12@XZ) referenced in function "int __cdecl MenuCommandHandler(struct API_MenuParams const *)" (?MenuCommandHandler@@YAHPEBUAPI_MenuParams@@@Z)
G:\dev\v27\JHP_Audit\out\build\x64-Release\JHP_Audit.obj : error LNK2019: unresolved external symbol "public: static void __cdecl JHP::LiveAudit::CreateInstance(void)" (?CreateInstance@LiveAudit@JHP@@SAXXZ) referenced in function "int __cdecl ProjectEventHandler(enum API_NotifyEventID,int)" (?ProjectEventHandler@@YAHW4API_NotifyEventID@@H@Z)
...
I am really out of my element here and have no idea where to even begin to look.
Thanks [once again] for pointing me in a right direction.
All the best - Chris
2024-01-11 05:07 PM - edited 2024-01-11 07:32 PM
I woke up at 2am last night in Texas thinking about this. I had to revise my CMakeList.txt file a bit to get it to work with a Linker issue on the first migrations from AC25 to AC27 and using CMake. The forum discussion about these these revisions can be seen HERE .
My CMakeList.txt file is here and the revision I am talking about involved adding the last line.
cmake_minimum_required (VERSION 3.16)
include (Tools/CMakeCommon.cmake)
set (API_DEVKIT_DIR $ENV{AC_API_DEVKIT_DIR} CACHE PATH "API DevKit directory.")
if (GITHUB_BUILD)
include(${CMAKE_BINARY_DIR}/conan_paths.cmake)
set (API_DEVKIT_DIR ${CONAN_ARCHICAD-APIDEVKIT_ROOT}/bin)
endif ()
set_property (GLOBAL PROPERTY USE_FOLDERS ON)
# set (CMAKE_CONFIGURATION_TYPES Debug;Release;RelWithDebInfo)
set (CMAKE_CONFIGURATION_TYPES Release)
set (AC_API_DEVKIT_DIR ${API_DEVKIT_DIR} CACHE PATH "API DevKit directory.")
set (AC_ADDON_NAME "JHP_Audit" CACHE STRING "AddOn Name")
set (AC_ADDON_LANGUAGE "INT" CACHE STRING "Add-On language code.")
project (${AC_ADDON_NAME} CXX)
message( STATUS ">>> AC_API_DEVKIT_DIR: $ENV{AC_API_DEVKIT_DIR}")
DetectACVersion (${AC_API_DEVKIT_DIR} ACVersion)
message (STATUS "Archicad Version: ${ACVersion}")
set (AddOnFolder .)
SetGlobalCompilerDefinitions ()
GenerateAddOnProject (${ACVersion} ${AC_API_DEVKIT_DIR} ${AC_ADDON_NAME} ${AddOnFolder} ${AC_ADDON_LANGUAGE})
set_target_properties(${AC_ADDON_NAME} PROPERTIES LINKER_LANGUAGE CXX)
Maybe that helps???
Have a great day - Chris
2024-01-11 08:18 PM - edited 2024-01-11 08:43 PM
Next day:
I moved on to the last custom add-on I want to migrate from 25 to 27. I receive the same message [error LNK2019: unresolved external symbol] when I build. This time, it is related to a dialog callback function. Output from Build is:
Building Custom Rule G:/dev/v27/JHP_Layouts/CMakeLists.txt
APICommon.c
JHP_Layouts.cpp
Generating Code...
G:\dev\v27\JHP_Layouts\out\build\x64-Release\JHP_Layouts.obj : error LNK2019: unresolved external symbol "short __cdecl JHP::Dialogs::ConsultantSheetsDialogCallback(short,short,short,__int64,__int64)" (?ConsultantSheetsDialogCallback@Dialogs@JHP@@YAFFFF_J0@Z) referenced in function "private: virtual int __cdecl std::_Func_impl_no_alloc<class <lambda_698cf9db7fb234a3b63567341aabf019>,int>::_Do_call(void)" (?_Do_call@?$_Func_impl_no_alloc@V<lambda_698cf9db7fb234a3b63567341aabf019>@@H$$V@std@@EEAAHXZ)
G:\dev\v27\JHP_Layouts\out\build\x64-Release\Release\JHP_Layouts.apx : fatal error LNK1120: 1 unresolved externals
Build All failed.
The code that this message is referencing is:
#pragma once
#include "DG.h"
#include "DGDialog.hpp"
namespace JHP
{
namespace Dialogs
{
short DGCALLBACK ConsultantSheetsDialogCallback(short message, short dialId, short item, DGUserData, DGMessageData);
}
}
One thing I notice is that these are the only projects with .cpp and .h files in subfolders below .\Src folder. Would a CMakeList.txt file be required in the subfolders as well? These subfolder files contain the functions in the Build error messages. Coincidence? Or maybe the reference to find the CMakeList.txt file is "..\CMakeList.txt" and needs to be modified to "..\CMakeList.txt; ..\..\CMakeList.txt".
Thanks to any insight that comes my way...
Chris
2024-01-11 08:56 PM
Check these two things that changed between AC25 and AC27:
Hope that helps.
2024-01-11 09:53 PM
@Viktor Kovacs - thanks for the reply. I have previously read the first link you provide regarding the toolset change.
I understood this
"If you try to use VS 2022 to build your AddOns, you have to keep in mind a few things."
with an emphasis on "try", as - - if I was using VS2022 with toolset 143, I need to back off to toolset 142, but since I was using VS2019 with toolset 142 [and not trying to use 2022], I was OK.
However, your second link really makes clear the need for C++17, which I had not picked up on until now. And I have not had any issues with prior migrations of four add-ons from 25 to 27. They are loading and working without issue in AC27.
I now understand my path is to change my current configuration [in red] to the necessary configuration [in green].
Any idea why the previous four add-ons are in working order for 27?
Or what about these last two are finally making me take notice?
Just curious...
You have been loads of help on this particular learning exercise.
It is greatly appreciated!
Chris
2024-01-16 09:34 PM - edited 2024-01-16 11:02 PM
Your second link references code in the CMakeCommon.cmake file:
target_compile_features (${target} PUBLIC cxx_std_17)
which seems like the CMake version of the /std:c++17 switch that will "Enable supported C and C++ language features from the specified version of the C or C++ language standard." and has been "available in Visual Studio 2017 and later. They're used to control the version-specific ISO C or C++ programming language standard features enabled during compilation of your code." This sounds like direction for the compiler which makes me think that the features of C++17 requiring this direction might be available to my VS2019 install [Version 16.11.30].
Am I thinking about this correctly?
Is this already part of my VS2019 install?
Is it something I need to [or even can] install to VS2019?
Just curious to understand this part of the puzzle before I rush right out and purchase an upgrade to VS2022.
Thanks for the info - chris