Helpful 5165 Thread

07/30/2010 01:51 Zkiller110#1
I'm making this for people that may have the same problems as me when they start making their servers. These may be permanent or temporary fixes but they all work for me so far.

My first problem I ran into was setting up the source I would keep getting this error:

Code:
PInvokeStackImbalance was detected
Message: A call to PInvoke function 'NewestCOServer!NewestCOServer.Native::memcpy' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
in this section of coding:

Code:
        unsafe void WaitData(IAsyncResult Res)
        {
            try
            {
                StateObj S = (StateObj)Res.AsyncState;
                SocketError SE;
                try
                {
                    if (S.Sock.Connected)
                    {
                        uint DataLen = (uint)S.Sock.EndReceive(Res, out SE);

                        if (SE == SocketError.Success && DataLen != 0)
                        {
                            byte[] RData = new byte[DataLen];
                            fixed (byte* p = RData, p2 = S.Data)
                                [COLOR="Red"]Native.memcpy(p, p2, DataLen);[/COLOR]
                            if (DataHandler != null)
                                DataHandler.Invoke(S, RData);

                            S.Sock.BeginReceive(S.Data, 0, 1024, SocketFlags.None, new AsyncCallback(WaitData), S);
                        }
                        else if (DCHandler != null)
                            DCHandler.Invoke(S);
                    }
                    else if (DCHandler != null)
                        DCHandler.Invoke(S);
                }
                catch
                {
                    if (DCHandler != null)
                        DCHandler.Invoke(S);
                }
            }
            catch (Exception Exc) { Program.WriteLine(Exc); }
        }
elite50 helped me fix this.
1. To fix it you have too run Navicat off of Appserv, I was running mine off the mysql server before.
2. You must have the database loaded in Navicat.
3. If running on a 64x computer must convert to 32 bit (86x).
4. This might not be the problem for everyone but I cannot log in to my server from debugging the source from C#, I must go to the source folder > bin > 86x > debug and run it from there.

**Use this for Native.cs it worked for me **
Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace NewestCOServer
{
    public unsafe class Native
    {
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetStdHandle(uint nStdHandle);
        [DllImport("kernel32.dll")]
        public static extern bool SetConsoleTextAttribute(IntPtr hConsoleOutput, int wAttributes);
        [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
        public static extern unsafe void* memcpy(void* dest, void* src, uint size);
        [DllImport("user32.dll")]
        public static extern int MessageBox(int h, string m, string c, int type);
        [DllImport("winmm.dll")]
        public static extern uint timeGetTime();
        [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static void BF_set_key(IntPtr _key, int len, byte[] data);
        [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static void BF_ecb_encrypt(byte[] in_, byte[] out_, IntPtr schedule, int enc);
        [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static void BF_cbc_encrypt(byte[] in_, byte[] out_, int length, IntPtr schedule, byte[] ivec, int enc);
        [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static void BF_cfb64_encrypt(byte[] in_, byte[] out_, int length, IntPtr schedule, byte[] ivec, ref int num, int enc);
        [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static void BF_ofb64_encrypt(byte[] in_, byte[] out_, int length, IntPtr schedule, byte[] ivec, out int num);
    }
}
That's all I know about that problem.

--------------------------------------------------------------------------

The next problem I ran into was when I created a character he/she would start with a random number of rebirths. I fixed this by going to database.cs and adding a catch to the loading character.

Find this line:
Code:
public static Game.Character LoadCharacter(string Name, ref string Account)
At the bottom of that LoadCharacter section there is this:
Code:
                        catch
                        {
                            C.VipLevel = 0;
                            C.ExpBallsUsedToday = 0;
                            C.LotteryUsed = 0;
                            C.TrainTimeLeft = 0;
                            C.InOTG = false;
                            C.LotteryUsed = 0;
                            C.WHPassword = "0";
                            C.Spouse = "None";
                            C.UniversityPoints = 0;
                        }
You want to add "C.Reborns = 0;"

Find this line:
Code:
public static Game.Robot LoadAsRobot(string Name, ref string Account)
At the bottom of that LoadAsRobot section there is this:
Code:
                        catch
                        {
                            C.VipLevel = 0;
                            C.ExpBallsUsedToday = 0;
                            C.LotteryUsed = 0;
                            C.Reborns = 0;
                            C.TrainTimeLeft = 0;
                            C.InOTG = false;
                            C.LotteryUsed = 0;
                            C.WHPassword = "0";
                            C.Spouse = "None";
                        }
You want to add "C.Reborns = 0;"

--------------------------------------------------------------------------

The reborn fix may just be temporary I'm not sure yet. That's all I got for now if I come up with anything else ill post it here
07/30/2010 03:09 Fish*#2
#Request move
07/30/2010 09:14 Huseby#3
#Moved
07/30/2010 09:29 ~Yuki~#4
I am totally sure your memory gets corrupt due not running Navicat. Yes. Sure. DUH!

PInvokeStackImbalance Exception on MemCPI wich is a NATIVE CALL has nothing to do with Navicat...

Waiting for korvacs to point out the things more clear. I could be mistaken on what i posted but i dont think i am. (Btw to "fix" that simply reboot the pc, or remove the Memcpi shit.)
07/30/2010 15:20 Korvacs#5
Indeed changing to Navicat will not fix this exception, the problem is that the Native call your PInvoking does not match that of the original Call, so occasionally it performs differently than intended and you basically screw the memory space being used by the server.

Specifically you need to be careful with the signiture of the pinvoke, you can give this a go for the memcpy issue:

Code:
[DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
        public static extern unsafe void* memcpy(void* dest, void* src, uint size);
I must point out that this works for me however ive only been using it for a short time and have never actually experience the stackimbalance.
07/31/2010 16:11 Zkiller110#6
Quote:
Originally Posted by Korvacs View Post
Indeed changing to Navicat will not fix this exception, the problem is that the Native call your PInvoking does not match that of the original Call, so occasionally it performs differently than intended and you basically screw the memory space being used by the server.

Specifically you need to be careful with the signiture of the pinvoke, you can give this a go for the memcpy issue:

Code:
[DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
        public static extern unsafe void* memcpy(void* dest, void* src, uint size);
I must point out that this works for me however ive only been using it for a short time and have never actually experience the stackimbalance.
i diid this but now it gives me a different error in blowfish.cs
Code:
PInvokeStackImbalance was detected
Message: A call to PInvoke function 'NewestCOServer!NewestCOServer.Native::BF_set_key' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
this is what is highlighted
Code:
        public void SetKey(byte[] data)
        {
            _encryptNum = 0;
            _decryptNum = 0;
            [COLOR="Red"]Native.BF_set_key(_key, data.Length, data);[/COLOR]
        }
and my native.cs is
Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace NewestCOServer
{
    public unsafe class Native
    {
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetStdHandle(uint nStdHandle);
        [DllImport("kernel32.dll")]
        public static extern bool SetConsoleTextAttribute(IntPtr hConsoleOutput, int wAttributes);
        [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
        public static extern unsafe void* memcpy(void* dest, void* src, uint size);
        [DllImport("user32.dll")]
        public static extern int MessageBox(int h, string m, string c, int type);
        [DllImport("winmm.dll")]
        public static extern uint timeGetTime();
        [DllImport("libeay32.dll")]
        public extern static void BF_set_key(IntPtr _key, int len, byte[] data);

        [DllImport("libeay32.dll")]
        public extern static void BF_ecb_encrypt(byte[] in_, byte[] out_, IntPtr schedule, int enc);

        [DllImport("libeay32.dll")]
        public extern static void BF_cbc_encrypt(byte[] in_, byte[] out_, int length, IntPtr schedule, byte[] ivec, int enc);

        [DllImport("libeay32.dll")]
        public extern static void BF_cfb64_encrypt(byte[] in_, byte[] out_, int length, IntPtr schedule, byte[] ivec, ref int num, int enc);

        [DllImport("libeay32.dll")]
        public extern static void BF_ofb64_encrypt(byte[] in_, byte[] out_, int length, IntPtr schedule, byte[] ivec, out int num);
    }
}
07/31/2010 16:29 Basser#7
I think it has to do with call convention or something similar, UnknownOne fixed it for me, you have to add 1 parameter for the CallingConvention, not sure what the value was, something like CallingConvention = Cdcl

EDIT:
Do what Korvacs did in his post, for every extern modifier starting with BF_.
07/31/2010 23:18 Zkiller110#8
Quote:
Originally Posted by Basser View Post
I think it has to do with call convention or something similar, UnknownOne fixed it for me, you have to add 1 parameter for the CallingConvention, not sure what the value was, something like CallingConvention = Cdcl

EDIT:
Do what Korvacs did in his post, for every extern modifier starting with BF_.
tried it just give me more errors
08/02/2010 00:04 Korvacs#9
Change this:

Code:
        [DllImport("libeay32.dll")]
To this:

Code:
        [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
And let me know if that works.
08/02/2010 06:15 Zkiller110#10
Quote:
Originally Posted by Korvacs View Post
Change this:

Code:
        [DllImport("libeay32.dll")]
To this:

Code:
        [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
And let me know if that works.
that worked thanks man
:handsdown::handsdown:
08/02/2010 07:31 xSynthesis#11
Memcpy issue causing by the version of .Net Framework you've got. Right click to solution > Properties > Application > Target Framework (Change the version of framework whichever you've got.)
Simple.
08/02/2010 10:54 Korvacs#12
Quote:
Originally Posted by xSynthesis View Post
Memcpy issue causing by the version of .Net Framework you've got. Right click to solution > Properties > Application > Target Framework (Change the version of framework whichever you've got.)
Simple.
Not true...memcpy is outside of the framework otherwise you wouldnt need to pinvoke it in the first place :facepalm:
08/02/2010 23:27 _DreadNought_#13
I knew were she was coming from, I had that and by changing my .net framework it fixed it :P
08/02/2010 23:37 Korvacs#14
Quote:
Originally Posted by Eliminationn View Post
I knew were she was coming from, I had that and by changing my .net framework it fixed it :P
It may fix it because the framework your now using correctly invokes the native call, however you should be using the latest framework and the correct convention otherwise your just going backwards...
08/02/2010 23:44 Basser#15
Quote:
Originally Posted by Korvacs View Post
It may fix it because the framework your now using correctly invokes the native call, however you should be using the latest framework and the correct convention otherwise your just going backwards...
Changing to 3.0 may fix it, but as Korvacs said, it is not the cause.
.NET Framework 4.0, is not the cause, it is has just changed the default settings, from the ones in 3.5, but hell no, it's not the framework doing anything wrong, you shouldn't fix it by lowering the version of your framework, but by using the right calling convention, as Korvacs stated.

Korvacs is correct, xSynthesis simply isn't.