Page 1 of 1

Purebasic To Csharp DLL Problem in Memory

Posted: Sun May 28, 2023 9:40 pm
by skinkairewalker
Guys, I'm currently creating a Dll for Csharp using some Purebasic network commands, when calling the function: ReceiveNetworkData(cid, *Buffer, memorySize), the C# program fails with error 3221226356 (0xc0000374).

below the snippet used to get the message on the network. Does anyone know what might be going on?

Code: Select all


ProcedureCDLL.s ServerDataString(cid.i,memorySize.i)

  If (*Buffer)
    FreeMemory(*Buffer)
  EndIf   

  *Buffer = AllocateMemory(memorySize)
  ReceiveNetworkData(cid, *Buffer, memorySize)
  MessageRequester("","mensagem recebida = "+PeekS(*Buffer, -1, #PB_Ascii))
   MessageRequester("","mensagem recebida 2 = "+Decrypt(PeekS(*Buffer, -1, #PB_Ascii),"MyPassword"))
  ;LastMessageSocket = Decrypt(PeekS(*Buffer, -1, #PB_Ascii),"MyPassword")

  ProcedureReturn Decrypt(PeekS(*Buffer, -1, #PB_Ascii),"MyPassword")

EndProcedure  


Re: Purebasic To Csharp DLL Problem in Memory

Posted: Tue May 30, 2023 8:30 am
by IceSoft
Do you think this is allowed?

Re: Purebasic To Csharp DLL Problem in Memory

Posted: Tue May 30, 2023 9:46 am
by Fred
Never return a string type from a ProcedureDLL, returns a pointer

Re: Purebasic To Csharp DLL Problem in Memory

Posted: Tue May 30, 2023 11:29 am
by AZJIO
I found this in Notepad++ plugin

Code: Select all

; DLL (plugin)
ProcedureCDLL.s getName()
	ProcedureReturn "Template"
EndProcedure

; name request
*pname = CallCFunction(LDirName()\id, "getName")
If Not *pname
	Continue
EndIf
LDirName()\pname = PeekS(*pname)
It is not right?

I did it, it works too

Code: Select all

ProcedureCDLL.i getName()
	ProcedureReturn @"Template"
EndProcedure

Re: Purebasic To Csharp DLL Problem in Memory

Posted: Tue May 30, 2023 3:38 pm
by Fred
This special case works because you are returning a literal string which is not dynamically allocated. If you return a local string variable instead, it will failed as the local variable is freed at the procedure end.

Re: Purebasic To Csharp DLL Problem in Memory

Posted: Tue May 30, 2023 3:39 pm
by skinkairewalker
Thanks for everyone's help! and thanks for the tip, Fred
I've tried every way, and I can't get it to work...

PureBasic Dll Code :

Code: Select all


DeclareCDLL.i getName()
DeclareCDLL.s getName2()
DeclareDLL.i getName3()
DeclareDLL.s getName4()

ProcedureCDLL.i getName()
	ProcedureReturn @"Template"
EndProcedure

ProcedureCDLL.s getName2()
	ProcedureReturn "Template"
EndProcedure

ProcedureDLL.i getName3()
	ProcedureReturn @"Template"
EndProcedure

ProcedureDLL.s getName4()
	ProcedureReturn "Template"
EndProcedure

CSharp Console Application .Net Code

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace DllTest
{


    internal class Program
    {
        [DllImport("STRDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern string getName();

        [DllImport("STRDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern string getName2();

        [DllImport("STRDLL.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern string getName3();

        [DllImport("STRDLL.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern string getName4();

        static void Main(string[] args)
        {

            Console.WriteLine("asd "+ getName());
            Console.ReadKey();

        }
    }
}

Either way, the return is the same: https://prnt.sc/ffOxCwZN_oRC , none make the C# program stay operational.

What could be happening?

Re: Purebasic To Csharp DLL Problem in Memory

Posted: Tue May 30, 2023 3:47 pm
by Fred
Did you tried something like this ?

Code: Select all

ProcedureCDLL.i getName2()
	ProcedureReturn UTF8("Template")
EndProcedure

Re: Purebasic To Csharp DLL Problem in Memory

Posted: Tue May 30, 2023 4:01 pm
by skinkairewalker
Fred wrote: Tue May 30, 2023 3:47 pm Did you tried something like this ?

Code: Select all

ProcedureCDLL.i getName2()
	ProcedureReturn UTF8("Template")
EndProcedure
directly like that, still persists in the error .

however, I discovered that the problem was directly in C#, look what I needed to do to make it work:

Purebasic Dll

Code: Select all


Declare ConvertString(String.s)

DeclareCDLL.i getName()
DeclareCDLL.i getName2()
DeclareDLL.i getName3()
DeclareDLL.s getName4()

ProcedureCDLL.i getName()
	ProcedureReturn ConvertString("Template")
EndProcedure

ProcedureCDLL.i getName2()
	ProcedureReturn UTF8("Template")
EndProcedure

ProcedureDLL.i getName3()
	ProcedureReturn @"Template"
EndProcedure

ProcedureDLL.s getName4()
	ProcedureReturn "Template"
EndProcedure

Procedure ConvertString(String.s)
  Size=StringByteLength(String)
  If Size>0
   Protected *Ptr=AllocateMemory(Size+2)
   If *Ptr
     PokeS(*Ptr, String, Size, #PB_Ascii)
     ProcedureReturn *Ptr
   EndIf
 EndIf
EndProcedure
C# Console Code :

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace DllTest
{


    internal class Program
    {
        [DllImport("STRDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr getName(); // 

        [DllImport("STRDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr getName2();

        [DllImport("STRDLL.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr getName3();

        [DllImport("STRDLL.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern string getName4();

        static void Main(string[] args)
        {

            IntPtr ptr = getName();
            IntPtr ptr2 = getName();
            string str = Marshal.PtrToStringAnsi(ptr);
            string str2 = Marshal.PtrToStringAnsi(ptr2);
            Console.WriteLine(str);
            Console.WriteLine(str2);

            Console.ReadKey();
     
        }
    }
}

instead of declaring :

Code: Select all

public static extern string getName();
i get the IntPtr , like you said above.
and now it works...

Re: Purebasic To Csharp DLL Problem in Memory

Posted: Tue May 30, 2023 4:42 pm
by Fred
Good, and now you need a procedure to free the allocated string, or it will leak.