简体   繁体   中英

Defining a variable once inside an infinite loop C++

I'm using Pylon SDK in my project. It's a SDK for Basler cameras.

I'm calling gimbalControl function in an infinite while loop in the main function.

In gimbalControl , I need to define variables and initialize the gimbal parts. Afterwards, I use those initialized and defined things in the rest of the function. Following is a sample of my code clarifying the problem.

void gimbalControl(void)
{
   try
   {
        // Only executed in the first iteration
        if(!gimbalInitialized)
        {
             setupGimbal();
             configConnection(); 
             PylonInitialize();

             // Create an instant camera object with the camera device found first.
             CInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice());

             // Open the camera before accessing any parameters
             camera.Open();

             // Start the grabbing of images
             camera.StartGrabbing();

             gimbalInitialized = true;
       }
       else
       {
            // Wait for an image and then retrieve it. A timout of 5000 ms is used.
            camera.RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException);  // CAUSES ERROR

            // Image not grabbed successfully?
            if (!ptrGrabResult->GrabSucceeded())
            {
                cout << "Cannot capture a frame from video stream" << endl;
            }
    }
    catch(...) // Catch all unhandled exceptions
    {
        printf("ERROR IN CAMERA CONNECTION\n");
    }
}

I tried to make this module class-based but I didn't know how to declare camera in the class to be used later in the object. Actually, I don't know what this kind of camera declaration is!

When I compile this code I got an error that camera was not declared in this scope . Question 1 : How can I define camera once in this infinite loop without raising this error?

Question 2 : How can I declare camera as a private variable inside a class?

One approach is to make camera static outside the try block:

static CInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice());
try {
    ...
} catch (...) {
    ...
}

This ensures that camera object gets initialized only once, and stays accessible on both sides of the else in the conditional.

To declare camera in your class, put CTlFactory::GetInstance().CreateFirstDevice() in the initializer list:

class MyClass {
private:
    CInstantCamera camera;
public:
    MyClass() : camera(CTlFactory::GetInstance().CreateFirstDevice()) {
    }
};

camera is just a regular initialization. In this case, you're just calling the constructor on CInstantCamera that takes whatever type CTlFactory::GetInstance().CreateFirstDevice() is as the only argument.

Scopes for all intents and purposes define the lifetime of objects. One object cannot realistically talk to another in a different scope, unless they share a parent scope. In this case, camera is defined within the scope of the first if conditional block scope, but you reference it in the else conditional block scope.

void gimbalControl(void)
{
   // scope #1

   try
   {
        // scope #2 (inherits #1)

        if(!gimbalInitialized)
        {
            // scope #3 (inherits #1, #2)
        }
        else
        {
            // scope #4 (inherits #1, #2)
        }
    }
    catch(...) 
    {
        // scope #5 (inherits #1)
    }
}

Notice how scope 4 only inherits 1 and 2 , and not 3 ? They are in the same parent level scope, so they do not have the same lifetimes. Objects cannot talk to each other (reasonably) within these scopes.

The solution, is to just initialize camera in scope 2 . Since you are calling this in a loop, you will need to make the declaration static , so that it's not constructed during each call, just the first one.

References - Scope , Storage Duration - see: static

Simply stated, if your main calls gimbalControl() in a loop, you'll have to declare whatever variable you want to only have once outside of gimbalControl. Either do it in main before the loop:

int main(){
  int myVar=0;  //only declareded once
  while(true){
    gimbalControl();
  }
}

or declare them as global variables. If you declare it in gimbalControl and call gimballControl multiple times, each time you call gimbalControll it will delcare it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM