Dancing Hoskuld
Deity
Could they be being used by Python. For the UI and mods.
Python bindings go the other way, they use boost:: python to export functions. They don't use this dllexport and dllimport interface. This interface is presumably used by only the exe.Could they be being used by Python. For the UI and mods.
DllExport makes the function accessible to the game exe. Don't change number of arguments if the function is exported (you can't tell the exe how to call) and don't export your own functions as the exe will never call them anyway.Q4:
Why some "CvGlobals" methods are prefixed with DLLExport ? What does that do in the code?
DllExport CvUnit* getBestDefender(PlayerTypes eOwner, PlayerTypes eAttackingPlayer = NO_PLAYER, const CvUnit* pAttacker = NULL, bool bTestAtWar = false, bool bTestPotentialEnemy = false, bool bTestCanMove = false) const;
CvUnit* getBestDefender(PlayerTypes eOwner, PlayerTypes eAttackingPlayer = NO_PLAYER, const CvUnit* pAttacker = NULL, bool bTestAtWar = false, bool bTestPotentialEnemy = false, bool bTestCanMove = false, bool bAssassinate = false, bool bClearCache = false) const; // Exposed to Python
DllExport void setAIAutoPlay(int iNewValue);
void setAIAutoPlay(PlayerTypes iPlayer, int iNewValue, bool bForced = false);
Yeah I had no idea that it was originally a DllExport function or I would've been more reluctant to use additional parameters. I'm curious how we've managed to have this not create a problem all this time. Perhaps it may help to explain why there is such a huge delay with getBestDefender that doesn't seem explainable just by the processing within it at times. I would also be very concerned of potential bugs that may be caused if the EXE thinks one thing is happening when the dll goes another way due to having a mock function for 'compatibility'. So I have to wonder if the original issues that demanded another parameter could be solved another way. I'm really curious what problems we could expect this situation to be causing.It seems at the revision 391 of AND repository (2010-09-19), @Afforess removed DllExport from CvGame:: setAIAutoPlay.
@Thunderbrd added two booleans (bAssissinate, bClearCache) to CvPlot::getBestDefender at revisions 8395 (2015-12-13) and 9972 (2018-03-12), respectively.
I am not saying you were wrong adding new functionality to this function. But we can take advantage of function overloading, to keep one copy of CvPlot::getBestDefender that is DllExport'ed, in the original signature.
It looks like this:
Second line is our current code. First line is for compatibility. Some adjustments are needed to the flow of the function too.Code:DllExport CvUnit* getBestDefender(PlayerTypes eOwner, PlayerTypes eAttackingPlayer = NO_PLAYER, const CvUnit* pAttacker = NULL, bool bTestAtWar = false, bool bTestPotentialEnemy = false, bool bTestCanMove = false) const; CvUnit* getBestDefender(PlayerTypes eOwner, PlayerTypes eAttackingPlayer = NO_PLAYER, const CvUnit* pAttacker = NULL, bool bTestAtWar = false, bool bTestPotentialEnemy = false, bool bTestCanMove = false, bool bAssassinate = false, bool bClearCache = false) const; // Exposed to Python
In the other case, setAIAutoPlay, the original function has this signature:
Our inherited function from AND has a different signature, which isCode:DllExport void setAIAutoPlay(int iNewValue);
(Note this line doesn't need DllExport; a function with this signature is never imported by the exe.)Code:void setAIAutoPlay(PlayerTypes iPlayer, int iNewValue, bool bForced = false);
We can also utilize function overloading to provide the original one, alongside our current one, for compatibility.
Some behaviors are hard-coded in the exe; we can at best guess from its dependencies how they are processed, and based on our assumptions write dll code that does not interfere.I would also be very concerned of potential bugs that may be caused if the EXE thinks one thing is happening when the dll goes another way due to having a mock function for 'compatibility'. So I have to wonder if the original issues that demanded another parameter could be solved another way. I'm really curious what problems we could expect this situation to be causing.
Actually I do understand that. I did something similar with some steps in size matters but not for these reasons. Save a variable elsewhere then call that variable in the function rather than sending it as a parameter. That could be done here I think.However, it's safe to refer to global context from the original functions, so we may try to convert the additional arguments to be somewhat global, like we can to the force-overwrite flag, if we ensure they always represent the correct object when looked up. I'm talking so abstract here 'cause I've not examined the two functions in question yet...
@Thunderbrd added two booleans (bAssissinate, bClearCache) to CvPlot::getBestDefender at revisions 8395 (2015-12-13) and 9972 (2018-03-12), respectively.
I am not saying you were wrong adding new functionality to this function. But we can take advantage of function overloading, to keep one copy of CvPlot::getBestDefender that is DllExport'ed, in the original signature.
It looks like this:
Second line is our current code. First line is for compatibility.Code:DllExport CvUnit* getBestDefender(PlayerTypes eOwner, PlayerTypes eAttackingPlayer = NO_PLAYER, const CvUnit* pAttacker = NULL, bool bTestAtWar = false, bool bTestPotentialEnemy = false, bool bTestCanMove = false) const; CvUnit* getBestDefender(PlayerTypes eOwner, PlayerTypes eAttackingPlayer = NO_PLAYER, const CvUnit* pAttacker = NULL, bool bTestAtWar = false, bool bTestPotentialEnemy = false, bool bTestCanMove = false, bool bAssassinate = false, bool bClearCache = false) const; // Exposed to Python
What is this file and how do you manipulate it?It's possible to redirect DllExports to another function using a *.def file. Look at the changes in my latest commit for an example.
Reference: https://docs.microsoft.com/en-us/cpp/build/reference/exports?view=vs-2019What is this file and how do you manipulate it?
/trunk/Sources/CvGameCoreDLL.def
?getBestDefender@CvPlot@@QBEPAVCvUnit@@W4PlayerTypes@@0PBV2@_N22@Z=?getBestDefenderExternal@CvPlot@@QBEPAVCvUnit@@W4PlayerTypes@@0PBV2@_N22@Z
class CvUnit * CvPlot::getBestDefender(enum PlayerTypes, enum PlayerTypes, class CvUnit const *, bool, bool, bool)
=
class CvUnit * CvPlot::getBestDefenderExternal(enum PlayerTypes, enum PlayerTypes, class CvUnit const *, bool, bool, bool)
A small correction: CvPlot::getBestDefender10602
- Fixed the DllExport CvUnit::getBestDefender
Ok, but if the EXE is calling getBestDefender, it would never know to do so with the proper parameters for those final two bools, which could mean, if it is calling for getBestDefender in sync with processing in the DLL that tells the EXE to call it, for whatever reason, it's going to come up with potentially a very different result than what the DLL comes up with. This seems a good solution for now and we'll see if there are any bugs stemming from that result disagreement, but it's hard to understand why the EXE even needs to call for getBestDefender, and it could really be a reason for a mysterious problem or set of problems, like perhaps some of the reasons we see the plot list disagree with the units on what units are where.Reference: https://docs.microsoft.com/en-us/cpp/build/reference/exports?view=vs-2019
Our CvGameCoreDLL.def is currently used [exclusively] for aliasing export functions, for example getX() and getY() of CvPlot, CvCity and CvUnit, are aliased to their viewport counterparts. There are many cases viewport uses this file to alias functions, such as city looping (which are CvPlayer functions).
That line seems to be complicated (they are internal names, decorated by MSVC compiler, cf. https://docs.microsoft.com/en-us/cpp/build/reference/decorated-names?view=vs-2019 ), but it is essentially saying:Code:?getBestDefender@CvPlot@@QBEPAVCvUnit@@W4PlayerTypes@@0PBV2@_N22@Z=?getBestDefenderExternal@CvPlot@@QBEPAVCvUnit@@W4PlayerTypes@@0PBV2@_N22@Z
Do you spot the tiny little equal sign in the midst of that line?Code:class CvUnit * CvPlot::getBestDefender(enum PlayerTypes, enum PlayerTypes, class CvUnit const *, bool, bool, bool) = class CvUnit * CvPlot::getBestDefenderExternal(enum PlayerTypes, enum PlayerTypes, class CvUnit const *, bool, bool, bool)
Also, in the header, now we must DllExport getBestDefenderExternal and undo DllExport to getBestDefender (which we use internally and takes two additional boolean parameters).
That way, we are exporting getBestDefenderExternal and making the name getBestDefender an alias to it (from the exe's point of view).
A small correction: CvPlot::getBestDefender![]()
Ok, but if the EXE is calling getBestDefender, it would never know to do so with the proper parameters for those final two bools, which could mean, if it is calling for getBestDefender in sync with processing in the DLL that tells the EXE to call it, for whatever reason, it's going to come up with potentially a very different result than what the DLL comes up with. This seems a good solution for now and we'll see if there are any bugs stemming from that result disagreement, but it's hard to understand why the EXE even needs to call for getBestDefender, and it could really be a reason for a mysterious problem or set of problems, like perhaps some of the reasons we see the plot list disagree with the units on what units are where.
Am I wrong here? I'm hoping I am.
I don't think the exe use the function for anything very important, as the exe does not handle AI decisions or unit movement.
The last bool is about clearing the cache or not, that is probably only needed in special cases and done when needed by the dll.
In any case, I don't think the exe would use the result in the same context as the dll in such a way that the dll code anywhere would depend on the exe to have the same result for it as the dll would get when clearing the cache.
This is only my intuition, I haven't looked deeper into it than what's been said in this forum lately.
If changes in the dll lead to problems with the exe those changes must be reverted if there's no possible workaround. Thats because we don't know what the exe does and the fact that we can't change the exe.
Maybe @alberts2 is using different version - Visual Studio 2019 (never version than you use) has Community edition.Any of you programmers know what I need to do to get my product working again?
View attachment 527512
I'm not sure how to get a product key. I thought this was free to use... Depending on how much it is, I could pay for the access I need, but if it's too much, this might mean I'm done here.
Any of you programmers know what I need to do to get my product working again?
View attachment 527512
I'm not sure how to get a product key. I thought this was free to use... Depending on how much it is, I could pay for the access I need, but if it's too much, this might mean I'm done here.
Hmm... I guess I need to hunt down how to download the community edition then. I'll take a look. Thanks for the tip.The Enterprise version isn't free only the Community Edition is free.
Thanks... seems to have worked. I can compile successfully after the 2019 upgrade it seems.