SRL Archive - Reflection Help

Access violations


superuser

2011-08-15 08:55:18

Hi,

Just wondering, if somebody knows why is the following causing random access violations?

try
while (Pos('lay a trap here', R_LastChatMessage()) <> 0) do
Wait(200);
except
WriteLn(ExceptionParam());
end;

This is starting to be really frustrating…

Edit:

All that I can think of, is that in Chat.simba this fails sometimes:

function R_LastChatMessage: String;
...

for i := 279 downto 180 do
begin
Result := R_GetInterfaceText(INTERFACE_CHAT, i);
if (not (Result = '')) then
Exit;
end;

...
end;

I mean, always from 279 to 180 without exceptions?

Brandon

2011-08-15 10:14:37

Things that give access violation: Functions being used as parameters.. U have to use a function as a parameter indirectly.. dunno why.

should be:


try
ChatMsg:= R_LastChatMessage;
while(Pos('lay a trap here', ChatMsg) <> 0) dp
wait(200);
except
writeln(ExceptionParam());
end;
Had to assign ChatMsg:= R_LastChatMessage; or else if u just plug it in directly, u get access violation..

it works exactly the same as interfaces.. This will give access violation error:

R_ClickInterface(R_GetChildInterface(Parent, Child), 1);
and this will not give access violation:
Child:= R_GetChildInterface(Parent, Child);
R_ClickInterface(Child, 1);

superuser

2011-08-15 13:37:52

From: ggzz
Things that give access violation: Functions being used as parameters.. U have to use a function as a parameter indirectly.. dunno why.

should be:


try
ChatMsg:= R_LastChatMessage;
while(Pos('lay a trap here', ChatMsg) <> 0) dp
wait(200);
except
writeln(ExceptionParam());
end;
Had to assign ChatMsg:= R_LastChatMessage; or else if u just plug it in directly, u get access violation..

it works exactly the same as interfaces.. This will give access violation error:

R_ClickInterface(R_GetChildInterface(Parent, Child), 1);
and this will not give access violation:
Child:= R_GetChildInterface(Parent, Child);
R_ClickInterface(Child, 1);


No that's not the issue. This happens only with R_LastChatMessage. For instance, with


function Foo(): string;
begin
result := 'abcdefg'
end;

try
while(Pos('lay a trap here', Foo()) <> 0) do
wait(200);
except
writeln(ExceptionParam());
end;

the violation does not happen.

Yago

2011-08-15 13:51:41

Someone using my smelter got an a-violation where it opened up node=smartfieldblahblahblah… I'm clueless as to why this happens.

It was in R2 btw

Brandon

2011-08-15 14:00:50

From: superuser
No that's not the issue. This happens only with R_LastChatMessage. For instance, with


function Foo(): string;
begin
result := 'abcdefg'
end;

try
while(Pos('lay a trap here', Foo()) <> 0) do
wait(200);
except
writeln(ExceptionParam());
end;
the violation does not happen.



That's because the function is NOT indirectly called.. yes your calling Foo() directly and foo returns a result.. it's using that result (string).. thats y u don't get a violation.

Just try what I said with the interfaces and u will see.. I use R_Lastchatmessage all the time and don't get access violation unless I do it the way u did in the first post..

when u use R_LastChatMessage as a parameter, it doesn't just return the string directly like your foo function.. but rather it returns a function that returns a string… thats why u get that error. It returns:

R_GetInterfaceText(Interface, i); which returns a string.. so your using a function as a parameter which uses another function to get its result will definitely give u access violation.

In calculus you'd actually have to get the value of the function inside first.. then use that value to solve the outer function.. the computer doesn't do that for u.. its the programmer's job to do the inside function first and then pass the result to the outer function.. C++ is strict on this too.. u can never use a function inside a function (used as a parameter).

Oh and I just compiled your first post.. I didn't get any errors.. Infact I found something weird with it.. it outputs:
<col=0000ff>Meh

whenever I do writeln(LastChatMessage);

EDIT: Use this: R_TrimHTML(R_LastChatMessage); that will take out the <Col=0000ff> thing.. see if it helps u. Oh yeah it also shows username..
so username: message.. might wanna trim that off.

Edit2: In reply to ur post below:
From: superuser
Sorry, but that is just bull :) This is 100% valid and working:
And the same should go to PS, and it will at least for Pascal itself. Besides, computer doesn't do anything for you when talking about programming, the compiler/interpreter does ;)

So the way I see this, is that this version of PS has a bug in it.


I like the ignorance.. first off ur code proves nothing.. thats not a function inside a function now is it? Thats functions inside classes.. no one said thats illegal. Functions inside functions are.. well declaring them are. Secondly The link below to Coh3n's post does exactly what I just told u to do.. which is to assign R_LastChatMessage to a variable.. Last but not least, u can be picky and call it a compiler/interpreter.. either way its still the programmer's job to do the work and the computer gives the result not the compiler/interpreter.. when u run a program it runs through ur computer bud, not ur compiler.. Last but not least.. if my post is bull, explain why it works then. Coh3n's post does exactly what I said. Good luck with ur scripting.

Shuttleu

2011-08-15 14:28:46

before anyone start complaining about this, i have spoken to wizzup and its something to do with PascalScript being all shitty, as soon as lape is released it should all be good

so its not simbas fault nor is it something we can fix

~shut

superuser

2011-08-15 14:29:48

From: ggzz
That's because the function is NOT indirectly called.. yes your calling Foo() directly and foo returns a result.. it's using that result (string).. thats y u don't get a violation.

Just try what I said with the interfaces and u will see.. I use R_Lastchatmessage all the time and don't get access violation unless I do it the way u did in the first post..

when u use R_LastChatMessage as a parameter, it doesn't just return the string directly like your foo function.. but rather it returns a function that returns a string… thats why u get that error. It returns:

R_GetInterfaceText(Interface, i); which returns a string.. so your using a function as a parameter which uses another function to get its result will definitely give u access violation.

In calculus you'd actually have to get the value of the function inside first.. then use that value to solve the outer function.. the computer doesn't do that for u.. its the programmer's job to do the inside function first and then pass the result to the outer function.. C++ is strict on this too.. u can never use a function inside a function (used as a parameter).


Sorry, but that is just bull :) This is 100% valid and working:


#include <string>
#include <iostream>

class A
{
public:
A()
: _sz("foo")
{
}

~A()
{
}

const std::string & Get() const
{
return _sz;
}

private:
std::string _sz;
};

class B
{
public:
B(A *a)
: _a(a)
{
}

~B()
{
delete _a;
}

std::size_t Len(const std::string &s)
{
return s.length();
}

void Do()
{
std::cout << Len(_a->Get()) << std::endl;
}

private:
A* _a;
};

int main()
{
B *b = new B(new A);

b->Do();

delete b;
}

And the same should go to PS, and it will at least for Pascal itself. Besides, computer doesn't do anything for you when talking about programming, the compiler/interpreter does ;)

So the way I see this, is that this version of PS has a bug in it.

mormonman

2011-08-15 14:55:41

Coh3n explained it partially. http://villavu.com/forum/showthread.php?t=65944

superuser

2011-08-15 17:55:41

From: ggzz
I like the ignorance.. first off ur code proves nothing.. thats not a function inside a function now is it? Thats functions inside classes.. no one said thats illegal. Functions inside functions are.. well declaring them are. Secondly The link below to Coh3n's post does exactly what I just told u to do.. which is to assign R_LastChatMessage to a variable.. Last but not least, u can be picky and call it a compiler/interpreter.. either way its still the programmer's job to do the work and the computer gives the result not the compiler/interpreter.. when u run a program it runs through ur computer bud, not ur compiler.. Last but not least.. if my post is bull, explain why it works then. Coh3n's post does exactly what I said. Good luck with ur scripting.


First off you do know that how C++, what you mentioned, classes work under the hood right? Those methods are nothing more than functions. Non-virtual member functions are resolved statically. That is, the member function is selected statically (at compile-time) based on the type of the pointer (or reference) to the object.

Second, your example works solely because it's a workaround to fix the actual problem. There shouldn't be any reason for this

Pos('abc', R_LastChatMessage())

to be invalid.

Last, don't take it to yourself. No reason to get angry about it :)

And P.S. The part which was bull was your statement that functions are not allowed to be parameters
in functions, especially in C++. Btw, this causes random access violations as well on Simba 0.97.x


type
TTest = record
x, y: integer;
end;

var
g_test, g_test2: TTest;

begin
g_test := g_test2;
end.

There, the workaround would be:


g_test.x := g_test2.x;
g_test.y := g_test2.y;

mormonman

2011-08-15 17:57:05

It has to do with custom records being used..PS is known to be buggy, sorry mate you just gotta find ghetto workarounds.

superuser

2011-08-15 17:58:22

From: mormonman
It has to do with custom records being used..PS is known to be buggy, sorry mate you just gotta find ghetto workarounds.


Yeah, I know :p Lets just hope the future versions are less, say, buggy…

mormonman

2011-08-15 18:02:27

From: superuser
Yeah, I know :p Lets just hope the future versions are less, say, buggy…


lape is the answer.

Brandon

2011-08-15 18:22:33

U don't pass it directly.. in c++ u do a function pointer. If the workarounds work.. use them thats all.

superuser

2011-08-15 18:31:54

From: ggzz
U don't pass it directly.. in c++ u do a function pointer. If the workarounds work.. use them thats all.


Yes, you are right. Just out of curiosity and to enlight me, can you give me an example in c++ what I shouldn't do?

Brandon

2011-08-15 18:37:51

From: superuser
Yes, you are right. Just out of curiosity and to enlight me, can you give me an example in c++ what I shouldn't do?



Function2(Function1());

full program:


void Function1()
{
cout<<"Meh";
}
void Function2(Function1());
{
}

int main()
{
Function2();
return 0;
}

Actual way to do it.. pointer to:

void Function1()
{
cout<<"meh";
}

void Function2(void(*Function1)())
{
(*Function1)();
}

int main()
{
Function2(&Function1);
return 0;
}

superuser

2011-08-15 18:51:19

From: ggzz
Function2(Function1());

full program:


void Function1()
{
cout<<"Meh";
}
void Function2(Function1());
{
}

int main()
{
Function2();
return 0;
}

Actual way to do it.. pointer to:

void Function1()
{
cout<<"meh";
}

void Function2(void(*Function1)())
{
(*Function1)();
}

int main()
{
Function2(&Function1);
return 0;
}


Of course you cannot declare a function like that :) That is just silly. I still don't get it how Pos('', Func()) would be the same thing tho :)

Btw, no need to return 0 as the standard says. This is how you do it valid, as you tried to show:

More like this:


// type (*pt2Function)(...) = NULL; // C
// type (CMyClass::*pt2Member)(...) = NULL; // C+

void Function1()
{
}

void Function2(void (*pt2Func)())
{
(*pt2Func)();
}

int main()
{
Function2(&Function1);
}

Brandon

2011-08-15 18:56:58

From: superuser
Of course you cannot declare a function like that :) That is just silly. I still don't get it how Pos('', Func()) would be the same thing tho :)

Btw, no need to return 0 as the standard says.


Uhh because it's passing Func() as a parameter of Pos? I don't see anywhere there a pointer :S

superuser

2011-08-15 19:04:28

From: ggzz
Uhh because it's passing Func() as a parameter of Pos? I don't see anywhere there a pointer :S


Omg, you do realize that I'm not defining function there? It is completely different to call


procedure Pos(s: string; Func());
begin
end;

than


...

function Func(): string;
begin
....
end;

begin
if (Pos('', Func())) then
...
end.

:duh: