memory functions

General discussion forum for Ams Plugin Maker
User avatar
Shrek
Registered User
Posts: 49
Joined: Mon Aug 12, 2013 10:10 pm

memory functions

Post by Shrek »

Using the memory functions is a bit confusing as AMSPM does not correlate to the windows API all that well for example I was looking how to allocate a buffer then fill it with a string and get the pointer to use and get a pointer to a structure as defined in the winapi guides, looking at the button example I can sort of piece things together say:

__Memory.NewArray(RECT) is a pointer to an already defined rect structure.
__Memory.NewArray(_char) is a pointer to a buffer created by __Memory.StringToChararray(string.rep("\0",nLength+1))

but I cant seem to find out how to free off the buffers that I would be creating, any help?
User avatar
Shrek
Registered User
Posts: 49
Joined: Mon Aug 12, 2013 10:10 pm

Post by Shrek »

Lets start again..................

How do I get a pointer to a structure?

How do I get the size of a structure?

How do I free a structure?

How do I create a buffer of x amount of bytes?

How do I get a pointer to a buffer I created?

How do I free a buffer I created?

How do I put a string in a buffer I created?

How do I retrieve a string from a buffer I created then passed it over to the api to fill in?

How do I use Unicode strings with buffers?
User avatar
Serkan
Developer
Developer
Posts: 214
Joined: Thu Jul 04, 2013 8:44 pm
Location: Windows.h
Contact:

Post by Serkan »

Shrek wrote: Using the memory functions is a bit confusing as AMSPM does not correlate to the windows API all that well for example I was looking how to allocate a buffer then fill it with a string and get the pointer to use and get a pointer to a structure as defined in the winapi guides, looking at the button example I can sort of piece things together say:

__Memory.NewArray(RECT) is a pointer to an already defined rect structure.
__Memory.NewArray(_char) is a pointer to a buffer created by __Memory.StringToChararray(string.rep("\0",nLength+1))

but I cant seem to find out how to free off the buffers that I would be creating, any help?
Hi

this application created for AMS users and they usually used to use wizards and ready made actions
and design of this application was made based on this idea , this memory and dll functions are using metatables and garbage collectors
so ,you do not need to free/delete/dealocate anything , they will automatically deleted by garbage collector

making a DLL/Memory handling system like Memory plugins that you familiar , will make things harder for users of this application
all of types are compatible with Windows API functions as long as you used __DLL.GetFunction() with proper declaration

but i realized that making an advanced memory class would be very good , and i am going to add a new class to implement DLL handling in native way
Shrek wrote: How do I get a pointer to a structure?
you will not need it in this program , because when you define a function with an argument as struct then everthing will be done automatically
Shrek wrote:Lets start again..................
How do I get the size of a structure?
currently there is no provided function to do that but you can easily multiply member sizes and then get actual size
Shrek wrote: How do I free a structure?
it is automated simply it is subject to garbage collection , but you can use variable = nil; to delete anything you want
this will call __gc() metamethod of specified data and it will be freed
Shrek wrote: How do I create a buffer of x amount of bytes?
actually you do not need to allocate buffer because this system does it for you and frees it when it is necessary

you will only need to allocate buffer for char arrays (string)

and you can make it like below ,this allocates a buffer in 100 characters length plus NULL
and fills buffer with NULLs

Code: Select all

local nLength = 100;
local buffer = __Memory.StringToChararray(string.rep("\0",nLength+1));
now you can pass buffer to any function that expects an argument like (char*) or derivatives

the above code is equivalent of the following

Code: Select all

char *buffer = malloc(sizeof(char)*100+1);
Shrek wrote: How do I get a pointer to a buffer I created?

Code: Select all

local nLength = 100;
local buffer = __Memory.StringToChararray(string.rep("\0",nLength+1));
the variable buffer is pointer to allocated buffer
Shrek wrote: How do I free a buffer I created?

Code: Select all

local nLength = 100;
local buffer = __Memory.StringToChararray(string.rep("\0",nLength+1));
it is subject to garbage collection but , by above sample

buffer = nil will free it
Shrek wrote: How do I put a string in a buffer I created?
you can make both at once

Code: Select all

local buffer = __Memory.StringToChararray("Hello World!!\0");
in above sample a buffer created and a string Hello World!! is assigned to it
Shrek wrote: How do I retrieve a string from a buffer I created then passed it over to the api to fill in?

Code: Select all

local buffer = __Memory.StringToChararray("Hello World!!\0");
local string_in_buffer =  __Memory.ChararrayToString(buffer);
__Memory.StringToChararray() : allocates a buffer (array of char) and puts string in it
__Memory.ChararrayToString() : gets string in a buffer
Shrek wrote: How do I use Unicode strings with buffers?
sorry currently not possible
User avatar
Shrek
Registered User
Posts: 49
Joined: Mon Aug 12, 2013 10:10 pm

Post by Shrek »

Thank you, you know I think it would be good if the help file had a Q & A section in it covering these questions.
User avatar
Shrek
Registered User
Posts: 49
Joined: Mon Aug 12, 2013 10:10 pm

Post by Shrek »

Code: Select all

_DragQueryFileA = __DLL.GetFunction(__Shell32,_int,"DragQueryFileA",_int,_int,_int,_int)
then

Code: Select all

   local B = __Memory.StringToChararray(string.rep("\0",266))
   if _DragQueryFileA(wParam,1,B,266) == 0 then
     return false
   else
     return true, __Memory.ChararrayToString(B)
   end

errors out, a pcall to debug gives "expected integer, got string " so its seeing B not as a pointer but a string changing the 3rd argument to _ptr crashes the app.
User avatar
Serkan
Developer
Developer
Posts: 214
Joined: Thu Jul 04, 2013 8:44 pm
Location: Windows.h
Contact:

Post by Serkan »

Please try it like below

Code: Select all

_DragQueryFileA = __DLL.GetFunction(__Shell32,_int,"DragQueryFileA",_int,_int,__Memory.NewArray(_char),_int)
User avatar
Shrek
Registered User
Posts: 49
Joined: Mon Aug 12, 2013 10:10 pm

Post by Shrek »

^^^^^^thanks
User avatar
Shrek
Registered User
Posts: 49
Joined: Mon Aug 12, 2013 10:10 pm

Post by Shrek »

GlobalLock returns a pointer to the first byte of a buffer, how do I get the text from that buffer? Tried:

Code: Select all

local l = _GlobalLock(h)
local t = __Memory.ChararrayToString(l)
_GlobalUnlock(h)
but t returns a garbled string.

Code: Select all

local h = _GlobalAlloc(0x42,String.Length(t) + 1)
local l = _GlobalLock(h)
-- put string on l
How do I put text on buffer l?
User avatar
Serkan
Developer
Developer
Posts: 214
Joined: Thu Jul 04, 2013 8:44 pm
Location: Windows.h
Contact:

Post by Serkan »

Is this a clipboard task or a drag and drop task ?

it would be good to see a complete function that you wrote
so ,i can show a working example , please upload a sample project if it is possible

if it is a private project then , please create a simple version and upload here

or you can send your project privately to me using PM or to support email

thanks.
User avatar
Shrek
Registered User
Posts: 49
Joined: Mon Aug 12, 2013 10:10 pm

Post by Shrek »

Hi mate, its nothing private as I'm literally just trying to understand the methods involved with AMP, here is some code:

Code: Select all

__User32 = __DLL.LoadLibrary("User32.dll", "stdcall")
__Kernel32 = __DLL.LoadLibrary("Kernel32.dll", "stdcall")
if (__User32) then
 _OpenClipboard = __DLL.GetFunction(__User32,_int,"OpenClipboard",_int)
 _GetClipboardData = __DLL.GetFunction(__User32,_int,"GetClipboardData",_int)
 _CloseClipboard = __DLL.GetFunction(__User32,_int,"CloseClipboard")
 _SetClipboardData = __DLL.GetFunction(__User32,_int,"SetClipboardData",_int,_int)
 _EmptyClipboard = __DLL.GetFunction(__User32,_int,"EmptyClipboard")
end
if (__Kernel32) then
 _GlobalLock = __DLL.GetFunction(__Kernel32,_int,"GlobalLock",_int)
 _GlobalUnlock = __DLL.GetFunction(__Kernel32,_int,"GlobalUnlock",_int)
 _GlobalAlloc = __DLL.GetFunction(__Kernel32,_int,"GlobalAlloc",_int,_int)
end


ClipGetText = function()
 if _OpenClipboard(Application.GetWndHandle()) == 0 then return "" end
 local h = _GetClipboardData(1)
 if h == 0 then
  _CloseClipboard()
  return ""
 end
 local l = _GlobalLock(h)
 if l == 0 then
  _CloseClipboard()
  return ""
 end
 -- t is a garbled string
 local t = __Memory.ChararrayToString(l)
 --
 _GlobalUnlock(h)
 _CloseClipboard()
 return t
end;
ClipSetText = function(t)
 if _OpenClipboard(Application.GetWndHandle()) == 0 then return end
 if _EmptyClipboard() == 0 then
  _CloseClipboard()
  return false
 end
 local h = _GlobalAlloc(0x42,String.Length(t) + 1)
 if h == 0 then
  _CloseClipboard()
  return false
 end
 local l = _GlobalLock(h)
 if l == 0 then
  _CloseClipboard()
  return false
 end
 -- Put t onto l (_GlobalLock(h))
 _GlobalUnlock(h)
 _SetClipboardData(1,h)
 _CloseClipboard()
 return true
end;

In the ClipGetText we have a buffer not created by APM so it's how to get the string from that buffer.

In the ClipSetText we have a buffer not created by APM so it's how to put the string on that buffer.

There is quite a few other winapi functions and structures that make buffers for you so presumably the method for getting text and setting text here will be the same although the clipboard is the first function I've come across that does not give you the buffer size.
Post Reply