Jump to content

Delphi and $3380


Recommended Posts

Hi everybody,

I need some help witch my application sending messages via $3380 to the FS. I don't know how to get this working, because I tried different ways but with the same result.

First way was a test how to send a char.

i := 5;
k := 'h'; //k = Char
FSUIPC_Write($3380, 1, @k, dwResult);
FSUIPC_Write($32FA, 2, @i, dwResult);
FSUIPC_Process(dwResult);

Result is 'h' ;)

Next one is sending a String

i := 5;
k := 'does this work?'; //k = String
FSUIPC_Write($3380, 1, @k, dwResult);
FSUIPC_Write($32FA, 2, @i, dwResult);
FSUIPC_Process(dwResult);

Result is 'h' again.

The next one I have tested was with an array of char (field)

texte := 'does this work?';  //String
SetLength(Field, Length(texte));
for a := 0 to Length(texte)-1 Do
  Field[a]:=texte[a+1];
for a := 0 to Length(field)-1 Do begin
  FSUIPC_Write($3380, 1, @field[a], dwResult);
end;
FSUIPC_Write($32FA, 2, @i, dwResult);
FSUIPC_Process(dwResult);

Result: The last element of the array '?'.

I have tested some other ways like replacing the FSUIPC call, but nothing made me happy. Maybe some else has an idea?

regards

Oliver

PS:@Pete I know you are not family with Delphi ;)

Link to comment
Share on other sites

First way was a test how to send a char.

i := 5;
k := 'h'; //k = Char
FSUIPC_Write($3380, 1, @k, dwResult);
FSUIPC_Write($32FA, 2, @i, dwResult);
FSUIPC_Process(dwResult);

One minor point there: the string should always be zero terminated, so for an "h" on its own you needed 2 characters, 'h' and a zero byte. You were just lucky that the next byte (in 3381) happened to be zero already.

Next one is sending a String

i := 5;
k := 'does this work?'; //k = String
FSUIPC_Write($3380, 1, @k, dwResult);
FSUIPC_Write($32FA, 2, @i, dwResult);
FSUIPC_Process(dwResult);

Result is 'h' again.

The length in the Write to 3380 is still only 1, so only 1 byte is written to 3380. you need the entire string length including the zero at the end.

for a := 0 to Length(field)-1 Do begin

FSUIPC_Write($3380, 1, @field[a], dwResult);

...

Result: The last element of the array '?'.

Not surprising when you look at your code. you are writing a charracter to 3380, then overwriting it with the next, etc, til the last. So, the only one left in 3380 is the last. Isn't that obvious?

I don't know why you'd want to write only one byte (character) at a time -- it is very inefficient -- but if you do you'd need to increment the offset (3380) each time too, otherwise, isn't it obvious that you are simply writing to the same location (3380) all the time?

Why not simply write the whole string at once?

FSUIPC_Write($3380, Length(field), @field[a], dwResult);

And don't forget to make sure there's a zero byte ending the string and included in the length.

Regards

Pete

Link to comment
Share on other sites

  • 2 months later...

Hello,

I'm just writing a program in C#, and II'm trying to do this:

int a = 0;
            fsuipc.FSUIPC_Write(0x3380, Convert.ToByte("Hello\0"), ref a, ref dwResult);
            fsuipc.FSUIPC_Write(0x32FA, 6, ref token, ref dwResult);

When I run it, I get an error saying that the "input string is invalid".

Help!

Thanks very much

James

Link to comment
Share on other sites

Hi James,

Convert.ToByte() is for converting a number string to a real byte. e.g. A string "255" is converted to a byte holding the value 255.

What you need to do is convert the string into an array of bytes.

To complicated things all .NET strings are unicode and FSUIPC wants the string in ASCII. .NET has some classes to do a conversion for you:

The following code will convert a string called "MyString" into a byte array called "datablock" and also do the unicode to ASCII conversion, and zero terminate it on the way.

byte[] datablock = new byte[MyString.Length + 1];

Encoding asciiEncoder = UTF7Encoding.ASCII;

asciiEncoder.GetBytes(MyString).CopyTo(datablock, 0);

You can then use the datablock with the FSUIPC_Write() overload that takes a byte array (byte[]). From memory I think there's an extra parameter on that one to tell it the length of the array.

Alternatively you could convert your code to use my .NET client DLL for FSUIPC. It has a number of advantages over the older SDK you are using, one being that it reads a writes .NET strings directly to and from FSUIPC. All of the above conversion is handled by the DLL. For details and downloads see the sticky post at the top of this forum:

http://forums.simflight.com/viewtopic.php?f=54&t=53255

Paul

Link to comment
Share on other sites

Hi. Thanks very much for that.

I've tried this:

string MyString = "Hi! How are you?";

            byte[] datablock = new byte[MyString.Length + 1];
            Encoding asciiEncoder = UTF7Encoding.ASCII;
            asciiEncoder.GetBytes(MyString).CopyTo(datablock, 0);

            int a = 0;

            fsuipc.FSUIPC_Write(0x3380, datablock, ref a, ref dwResult);
            fsuipc.FSUIPC_Write(0x32FA, 6, ref token, ref dwResult);

I'm afraid I get the error "cannot convert from byte[] from byte"

Thanks!

James

Link to comment
Share on other sites

fsuipc.FSUIPC_Write(0x3380, datablock, ref a, ref dwResult);

I'm afraid I get the error "cannot convert from byte[] from byte"

That's the wrong overload. You need to use this one that accepts the byte array and also the length of the byte array:

fsuipc.FSUIPC_Write(0x3380, datablock.length, ref datablock, ref a, ref dwResult);

Try that.

Paul

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.