Script link failed - problems with importing and exporting.

Started by mode7, Tue 10/01/2012 11:54:32

Previous topic - Next topic

mode7

I opened a thread yesterday about getting null pointer errors with falsely exported struct variables.

I went on and changed it and it worked fine - in one script. I did exactly the same thing in another and get a script link error
I have three modules with the following hierachy

- Rectangle.asc/h
-Rectangle_Operation.asc/h
-GlobalScript.asc/h

the headers contain struct declarations and struct variable imports

Well lets take a look at it
Rectangle.ash
Code: ags

struct Rects
{
...
};

import Rects Rect;

Rectangle.asc
Code: ags

Rects Rect;

...lots of fancy stuff...

(end of script)
export Rect;


This works perfect so far (thanks again khris!)

Now I did this in the rectangle_operations script as well
Rectangle_operations.ash
Code: ags

struct Rectangles
{
...
};

import Rectangles Rectangle;

Rectangle_operations.asc
Code: ags

Rectangles Rectangle;

...lots of fancy stuff...

(end of script)
export Rectangle;


As you see this is done in exactly the same manner as the first one, however when
GlobalScript.asc calls any memeber function of Rectangle ags throws a script link failed error at me.

It seems completely random as i can access members of Rect without a problem. Please Help!

Khris

Not sure if just a typo:

Code: ags
import Rectangle Rectangles;

should be
Code: ags
import Rectangles Rectangle;


Could you post the complete error meessage? Because it mentions the import that fails.

You can move the export unter the declaration btw, no need to have it at the end of the script.

mode7

It was only a type it's spelled correctly in the script

The complete error reads

"script link failed: Runtime Error: Unresolved import 'Rectangle'"

it's if rectangle was never properly exported...

Khris

With functions, the syntax is slightly different:

Code: ags
// header

struct Rectangles {
  import function DoSomething(...);
}

// main script

function Rectangles::DoSomething(...) {
  ...
};


Since you say "when GlobalScript.asc calls any member function", it sounds like you're getting the error during the game, but I guess it IS a compile time error, right?

mode7

It is a compile error but I've tracked to the extend that it only occurs when I try to access a member of Rectangle

I think i did it right..
have a look

Header
Code: ags

struct Rectangles
{
  import function Move(int ID, int toX, int toY, float seconds);
  import bool IsIntersecting(int left1,int top1,int right1,int bottom1,int left2,int top2,int right2,int bottom2);
  import function HandleCollision(int ID1,  int ID2);
};

import Rectangles Rectangle;


Script (partial)
Code: ags


Rectangles Rectangle;
export Rectangle;

function Rectangles::Move(int ID, int toX, int toY, float seconds)
{
  float time = IntToFloat(GetGameSpeed())*seconds;
  float xoffset = IntToFloat(toX)-IntToFloat(Rect.GetX(ID));
  float yoffset = IntToFloat(toY)-IntToFloat(Rect.GetY(ID));
  
  if (time < 1.0) time = 1.0;
  
  float xrate = xoffset/time; 
  float yrate = yoffset/time;
  
  Rect.AddMovement(ID, xrate, yrate, FloatToInt(time));
}


bool Rectangles::IsIntersecting(int left1,int top1,int right1,int bottom1,int left2,int top2,int right2,int bottom2)
{
	return !(left1 > right2 || right1 < left2 ||
		top1 > bottom2 || bottom1 < top2);
}


function Rectangles::HandleCollision(int ID1,  int ID2)
{
  int stepsX = Rect.GetNextX(ID1)-Rect.GetX(ID1);
  int stepsY = Rect.GetNextY(ID1)-Rect.GetY(ID1);
  
  int Top1 = Rect.GetNextY(ID1);
  int Top2 = Rect.GetNextY(ID2);
  int Bottom1 = Rect.GetNextY(ID1)+Rect.GetHeight(ID1);
  int Bottom2 = Rect.GetNextY(ID2)+Rect.GetHeight(ID2);
  int Left1 = Rect.GetNextX(ID1);
  int Left2 = Rect.GetNextX(ID2);
  int Right1 = Rect.GetNextX(ID1)+Rect.GetWidth(ID1);
  int Right2 = Rect.GetNextX(ID1)+Rect.GetWidth(ID2); 
  if (Rectangle.IsIntersecting(Left1, Top1, Right1, Bottom1, Left1, Top1, Right2, Bottom2)) Display ("Collision!");
}

Khris

I'm not sure exactly why the error occurs at this point but try removing these lines:

Code: ags
import Rectangles Rectangle;

Rectangles Rectangle;
export Rectangle;


Since there's no data in the struct, you don't need an instance. You're simply using the struct to group the functions. Now add "static" in front of "function" and "bool", both in the header and main script.
Do the same for your Rect script, then change the struct names from "Rects" to "Rect" and from "Rectangles" to "Rectangle". Then all calls will point directly to the static struct, not the instance.
Now it should compile and run fine.


-----

I'd have done things slightly differently. Maybe that doesn't work for you due to what you're doing but here goes:

Code: ags
// header

struct str_rectangle {
  int x, y, width, height;
  float xrate, yrate;
  import int GetNextX();
  import int GetNextY();
  ...
};

import str_rectangle Rectangle[200];

// main

str_rectangle Rectangle[200];
export Rectangle;

int str_rectangle::GetNextX() {
  return this.x + FloatToInt(this.xrate*time_step);
}


Then a static struct like described for functions concerning not a single rectangle:

Code: ags
static bool Rectangles::AreIntersecting(int ID1, int ID2) {

  return !(Rectangle[ID1].x > Rectangle[ID2].x ...
}

mode7

Thanks Khris, you saved my day once again. Even though this is a kind of workaround its perfectly suitable for my structs as data structs are handled internal and only passed through to the public struct.

I didnt knew you could use structs this way.

Now everthing works fine.

SMF spam blocked by CleanTalk