Purebasic To Csharp DLL Problem in Memory

Just starting out? Need help? Post your questions and find answers here.
User avatar
skinkairewalker
Enthusiast
Enthusiast
Posts: 627
Joined: Fri Dec 04, 2015 9:26 pm

Purebasic To Csharp DLL Problem in Memory

Post 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  

User avatar
IceSoft
Addict
Addict
Posts: 1616
Joined: Thu Jun 24, 2004 8:51 am
Location: Germany

Re: Purebasic To Csharp DLL Problem in Memory

Post by IceSoft »

Do you think this is allowed?
Belive!
<Wrapper>4PB, PB<game>, =QONK=, PetriDish, Movie2Image, PictureManager,...
Fred
Administrator
Administrator
Posts: 16617
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Purebasic To Csharp DLL Problem in Memory

Post by Fred »

Never return a string type from a ProcedureDLL, returns a pointer
AZJIO
Addict
Addict
Posts: 1312
Joined: Sun May 14, 2017 1:48 am

Re: Purebasic To Csharp DLL Problem in Memory

Post 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
Fred
Administrator
Administrator
Posts: 16617
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Purebasic To Csharp DLL Problem in Memory

Post 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.
User avatar
skinkairewalker
Enthusiast
Enthusiast
Posts: 627
Joined: Fri Dec 04, 2015 9:26 pm

Re: Purebasic To Csharp DLL Problem in Memory

Post 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?
Fred
Administrator
Administrator
Posts: 16617
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Purebasic To Csharp DLL Problem in Memory

Post by Fred »

Did you tried something like this ?

Code: Select all

ProcedureCDLL.i getName2()
	ProcedureReturn UTF8("Template")
EndProcedure
User avatar
skinkairewalker
Enthusiast
Enthusiast
Posts: 627
Joined: Fri Dec 04, 2015 9:26 pm

Re: Purebasic To Csharp DLL Problem in Memory

Post 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...
Fred
Administrator
Administrator
Posts: 16617
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Purebasic To Csharp DLL Problem in Memory

Post by Fred »

Good, and now you need a procedure to free the allocated string, or it will leak.
Post Reply