Search code examples
c++builderindy

Problems using GStack->GetLocalAddressList(LList) in C++


I am trying to use the GetLocalAddressList() as referenced in https://www.indyproject.org/2014/03/14/tidstack-addlocaladdressestolist-method-is-now-deprecated/

I have translated the Delphi code to C++

#include <IdStack.hpp>

TIdStackLocalAddressList* LList;
TIdStackLocalAddress* LAddr;
int idx;

try {
    LList = new TIdStackLocalAddressList();
    try {
        GStack->GetLocalAddressList(LList);
        for (idx = 0; idx < LList->Count - 1; idx++) {
            LAddr = LList->Addresses[idx];
            switch (LAddr->IPVersion) {
                case Id_IPv4:
                    // Add to list Items
                    ListBox1->Items->Add(LAddr->IPAddress);
                    break;
                case Id_IPv6:
                    break;
                default:;
            }
        }
    } catch (...) {
    }
} __finally
{
    delete LList;
}

I get

Project Project1.exe raised exception class 0xc0000005 with message 'Exception 0xc0000005 encountered at address 0x408b38: Access violation reading location 0x00000000'.

When I execute GStack->GetLocalAddressList(LList);

I assume that it is because I haven't made a GStack object, but I have no reference as to how/when to do that. I have looked on the web an can't seem to find any good references for using Indy with Builder :(

Can someone help out? Thanks is advance.


Solution

  • GStack is a global singleton object that Indy uses to abstract access to platform-specific APIs.

    If you have other Indy components alive at the time you run this code, the GStack object is already created for you. But if there are no objects alive, you have to create the GStack object before you can use it.

    Fortunately, the singleton is reference-counted - it is created when the 1st reference is added, and then destroyed when the last reference is removed. The TIdStack class has public static methods for managing this reference counting. You should use those methods when using GStack directly, if you are not sure whether other Indy components are alive or not, eg:

    TIdStack::IncUsage(); // creates GStack if needed
    try
    {
        // now you can safely use GStack as needed...
    }
    __finally
    {
        TIdStack::DecUsage();  // destroys GStack if needed
    }
    

    On a side note, your for loop should not be subtracting 1 from the LList->Count when using the < comparison. The loop should be:

    for (idx = 0; idx < LList->Count; idx++)