Attribute and Error "NULL pointer passed"

Started by GoodGuy, Fri 17/03/2017 14:54:16

Previous topic - Next topic

GoodGuy

Issue from Wiki title
QuoteA VERY important point to make here is that you can NOT use an attribute in the same script where the getter and setter methods are defined. If you try, you'll get an error like this:

---------------------------
Adventure Game Studio
---------------------------
An internal error has occurred. Please note down the following information.
If the problem persists, post the details on the AGS Technical Forum.
(ACI version 3.20.1101)

Error: is_script_import: NULL pointer passed

---------------------------
OK   
---------------------------

Not particularly friendly as it doesn't actually tell you what's going on, leaving you to ask, "WTF?!?" Just note again that this is all unsupported technology so if you did go post in the Technical Forum you're likely to get asked what you think you're doing...In case you do see that error try looking for cases where you've used an attribute in the same script where its accessor functions are defined. If you need access to that value, use the property (or whatever else is storing the data) or call the get or set function directly.
But AGS is not able to import a structure. Or Don't I understand?

GoodGuy

I have a structure with attribute in script, but I didn't call attributes from this script. How can I fix it (I maybe don't understand smt)?

Crimson Wizard

What is the error exactly, can you show the part of the script that causes it?

"NULL pointer" error is usually an indication that you are using an uninitialized pointer variable.

By the way, frankly I think that Wiki article may be outdated, because I was getting different kind of error when trying to use struct's attribute in the same script.

GoodGuy

For example new script
Code: ags
struct Weapon {
   protected String damage; // this is our actual property to store the damage
   import attribute String Damage; // this of course is our attribute
   import String get_Damage();
   import void set_Damage(String damage);
 };
 
 String Weapon::get_Damage() {
   return this.damage; // return the data stored in the actual property
 }
 
 void Weapon::set_Damage(String damage) {
   //smt
   this.damage = damage;
 }
 
 int TIME = 0;
 Weapon Sword;
 function repeatedly_execute_always() {
   TIME++;
   if (TIME == 160)
   {
     Sword.Damage = "Hi!";
     Display("Works %s", Sword.Damage);
   }   
 }

Now there is error:

GoodGuy

import function doesn't work.
Header
Code: ags
import function Smt2();

Script
Code: ags
// new module script
    struct Weapon {
       protected String damage; // this is our actual property to store the damage
       import attribute String Damage; // this of course is our attribute
       import String get_Damage();
       import void set_Damage(String damage);
     };
     
     String Weapon::get_Damage() {
       return this.damage; // return the data stored in the actual property
     }
     
     void Weapon::set_Damage(String damage) {
       //smt
       this.damage = damage;
     }
     
     int TIME = 0;
     Weapon Sword;
     function Smt2() {
         Sword.Damage = "Hi!";
         Display("Works %s", Sword.Damage);
     }

Global Script
Code: ags

//another code
int TIME = 0;
function repeatedly_execute_always() {
  TIME++;
  if (TIME == 40)
  {
    TIME = 0;
    Smt2();
  }
}



Crimson Wizard

#5
Quote from: GoodGuy on Sun 02/04/2017 05:35:44
I have a structure with attribute in script, but I didn't call attributes from this script. How can I fix it (I maybe don't understand smt)?

You ARE calling attributes from the same script where getter and setter are defined:
Code: ags

     function Smt2() {
         Sword.Damage = "Hi!";
         Display("Works %s", Sword.Damage);
     }

Damage is the attribute, and you are using it in same script.
This is what the warning in wiki was about.

You need to change Sword.Damage to calling actual functions:
Code: ags

     function Smt2() {
         Sword.set_Damage("Hi!");
         Display("Works %s", Sword.get_Damage());
     }

GoodGuy

Quote from: Crimson Wizard on Sun 02/04/2017 17:31:23
You ARE calling attributes from the same script where getter and setter are defined:
Code: ags
    struct Weapon {
       protected String damage; // this is our actual property to store the damage
       import attribute String Damage; // this of course is our attribute
       import String get_Damage();
       import void set_Damage(String damage);
     };
     
     String Weapon::get_Damage() {
       return this.damage; // return the data stored in the actual property
     }
     
     void Weapon::set_Damage(String damage) {
       //smt
       this.damage = damage;
     }
     
     int TIME = 0;
     Weapon Sword;
     function repeatedly_execute_always() {
       TIME++;
       if (TIME == 160)
       {
         Sword.Damage = "Hi!";
         Display("Works %s", Sword.Damage);
       }   
     }

There is error in fourth second(

Quote from: Crimson Wizard on Sun 02/04/2017 17:31:23
You need to change Sword.Damage to calling actual functions:
Code: ags

     function Smt2() {
         Sword.set_Damage("Hi!");
         Display("Works %s", Sword.get_Damage());
     }

But it is two simple functions, not attribute.

Crimson Wizard

#7
I have a feeling that we do not understand each other.

You declared a struct with an attribute inside:
Code: ags

struct Weapon {
       protected String damage; // this is our actual property to store the damage
       import attribute String Damage; // this of course is our attribute
       import String get_Damage();
       import void set_Damage(String damage);
     };


"Damage" is an attribute. Functions get_Damage and set_Damage are functions that are used by the attribute.
When you write "Sword.Damage = X", set_Damage is called instead. When you write "String dam = Sword.Damage;", get_Damage is called instead.

AGS currently has a limitation that you cannot use attribute directly in the same script where you define these get_ and set_ functions. So, if you need to use that attribute in same script, then instead of "Sword.Damage" you need to use "Sword.get_Damage()" or "Sword.set_Damage(x)";

In all other scripts you may write "Sword.Damage".


UPD: I realized I skipped another thing in your very fist post:
Quote from: GoodGuy on Fri 17/03/2017 14:54:16
But AGS is not able to import a structure. Or Don't I understand?
In AGS you can import structure simply by declaring it in the script header. Then this structure will be available in all the lower scripts.
Just move your struct declaration out of the script module body (asc) to the header (ash).





Another thing is, that when I test your script I get error "script link failed", like the one you spoke of first: http://i.imgur.com/CksX0Yl.png

But in following posts you mention different types of errors:
http://i.imgur.com/KCuPtC0.png
http://i.imgur.com/buTpomP.png

This makes me suspect that you are not posting the actual latest version of your script.

GoodGuy

Quote from: Crimson Wizard on Wed 05/04/2017 09:06:48
"Damage" is an attribute. Functions get_Damage and set_Damage are functions that are used by the attribute.
When you write "Sword.Damage = X", set_Damage is called instead. When you write "String dam = Sword.Damage;", get_Damage is called instead.

AGS currently has a limitation that you cannot use attribute directly in the same script where you define these get_ and set_ functions. So, if you need to use that attribute in same script, then instead of "Sword.Damage" you need to use "Sword.get_Damage()" or "Sword.set_Damage(x)";

In all other scripts you may write "Sword.Damage".
Oh, that's the problem)
Quote from: Crimson Wizard on Wed 05/04/2017 09:06:48
This makes me suspect that you are not posting the actual latest version of your script.
Maybe. But I thank you for clarification, I understood this features.
Quote from: Crimson Wizard on Wed 05/04/2017 09:06:48
In AGS you can import structure simply by declaring it in the script header. Then this structure will be available in all the lower scripts.
Just move your struct declaration out of the script module body (asc) to the header (ash).
It is works. Thanks.
Attribute.ash
Code: ags
struct Weapon {
       protected String damage; // this is our actual property to store the damage
       import attribute String Damage; // this of course is our attribute
       import String get_Damage();
       import void set_Damage(String damage);
     };

Attribute.asc
Code: ags
     String Weapon::get_Damage() {
       return this.damage; // return the data stored in the actual property
     }
     
     void Weapon::set_Damage(String damage) {
       //smt
       this.damage = damage;
     }

Lower script "Without Attribute.asc"
Code: ags
     int TIME = 0;
     Weapon Sword;
    function repeatedly_execute_always() {
       TIME++;
       if (TIME == 160)
       {
         Sword.Damage = "Hi!";
         Display("Works %s", Sword.Damage);
       }   
     }

AGS displayed "Works Hi!" in the fourth second.

SMF spam blocked by CleanTalk