Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions API/RainmeterAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,60 @@ public void LogF(LogType type, string format, params Object[] args)
RmLog(this.m_Rm, type, string.Format(format, args));
}
}

/// <summary>
/// Helper for returning strings back to Rainmeter as an IntPtr.
/// </summary>
/// <example>
/// <code>
/// [DllExport]
/// public static IntPtr GetString(IntPtr data)
/// {
/// return Rainmeter.StringBuffer.Update("hello");
/// }
/// </code>
/// </example>
public sealed class StringBuffer
{
private static readonly StringBuffer s_Instance = new StringBuffer();

private IntPtr m_Buffer = IntPtr.Zero;

static StringBuffer()
{
}

private StringBuffer()
{
}

~StringBuffer()
{
FreeBuffer();
}

private void FreeBuffer()
{
if (m_Buffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(m_Buffer);
m_Buffer = IntPtr.Zero;
}
}

public static IntPtr Update(string value)
{
s_Instance.FreeBuffer();
s_Instance.m_Buffer = value != null ? Marshal.StringToHGlobalUni(value) : IntPtr.Zero;
return s_Instance.m_Buffer;
}

public static IntPtr Get()
{
return s_Instance.m_Buffer;
}
}

/// <summary>
/// Dummy attribute to mark method as exported for DllExporter.exe.
/// </summary>
Expand Down
37 changes: 8 additions & 29 deletions C#/PluginEmpty/PluginEmpty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@

// Overview: This is a blank canvas on which to build your plugin.

// Note: GetString, ExecuteBang and an unnamed function for use as a section variable
// Note: GetString, ExecuteBang and MyCustomFunction for use as a section variable
// have been commented out. If you need GetString, ExecuteBang, and/or section variables
// and you have read what they are used for from the SDK docs, uncomment the function(s)
// and/or add a function name to use for the section variable function(s).
// and you have read what they are used for from the SDK docs, uncomment the function(s).
// Otherwise leave them commented out (or get rid of them)!

namespace PluginEmpty
Expand All @@ -19,7 +18,8 @@ static public implicit operator Measure(IntPtr data)
{
return (Measure)GCHandle.FromIntPtr(data).Target;
}
public IntPtr buffer = IntPtr.Zero;

// Include your measure data/functions here.
}

public class Plugin
Expand All @@ -35,10 +35,7 @@ public static void Initialize(ref IntPtr data, IntPtr rm)
public static void Finalize(IntPtr data)
{
Measure measure = (Measure)data;
if (measure.buffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(measure.buffer);
}

GCHandle.FromIntPtr(data).Free();
}

Expand All @@ -52,23 +49,14 @@ public static void Reload(IntPtr data, IntPtr rm, ref double maxValue)
public static double Update(IntPtr data)
{
Measure measure = (Measure)data;

return 0.0;
}

//[DllExport]
//public static IntPtr GetString(IntPtr data)
//{
// Measure measure = (Measure)data;
// if (measure.buffer != IntPtr.Zero)
// {
// Marshal.FreeHGlobal(measure.buffer);
// measure.buffer = IntPtr.Zero;
// }
//
// measure.buffer = Marshal.StringToHGlobalUni("");
//
// return measure.buffer;
// return Rainmeter.StringBuffer.Update("");
//}

//[DllExport]
Expand All @@ -78,19 +66,10 @@ public static double Update(IntPtr data)
//}

//[DllExport]
//public static IntPtr (IntPtr data, int argc,
//public static IntPtr MyCustomFunction(IntPtr data, int argc,
// [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 1)] string[] argv)
//{
// Measure measure = (Measure)data;
// if (measure.buffer != IntPtr.Zero)
// {
// Marshal.FreeHGlobal(measure.buffer);
// measure.buffer = IntPtr.Zero;
// }
//
// measure.buffer = Marshal.StringToHGlobalUni("");
//
// return measure.buffer;
// return Rainmeter.StringBuffer.Update("");
//}
}
}
Expand Down
76 changes: 23 additions & 53 deletions C#/PluginSectionVariables/PluginSectionVariables.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
/*
Copyright (C) 2017 Trevor Hamilton
Copyright (C) 2017 Trevor Hamilton

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using System;
Expand Down Expand Up @@ -68,8 +68,8 @@ static public implicit operator Measure(IntPtr data)
{
return (Measure)GCHandle.FromIntPtr(data).Target;
}
public string inputStr; //The string returned in GetString is stored here
public IntPtr buffer; //Prevent marshalAs from causing memory leaks by clearing this before assigning

public string inputStr;
}

public class Plugin
Expand All @@ -87,7 +87,6 @@ public static void Reload(IntPtr data, IntPtr rm, ref double maxValue)
Measure measure = (Measure)data;
Rainmeter.API api = (Rainmeter.API)rm;

//Read measure for an Input string
measure.inputStr = api.ReadString("Input", "");
}

Expand All @@ -102,72 +101,43 @@ public static double Update(IntPtr data)
public static IntPtr GetString(IntPtr data)
{
Measure measure = (Measure)data;
if (measure.buffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(measure.buffer);
measure.buffer = IntPtr.Zero;
}

measure.buffer = Marshal.StringToHGlobalUni(measure.inputStr);
return measure.buffer;
return Rainmeter.StringBuffer.Update(measure.inputStr);
}

[DllExport]
public static IntPtr ToUpper(IntPtr data, int argc,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 1)] string[] argv)
{
Measure measure = (Measure)data;
if (measure.buffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(measure.buffer);
measure.buffer = IntPtr.Zero;
}

//If we are given one or more arguments convert to uppercase the first one
// If we are given one or more arguments convert to uppercase the first one
if (argc > 0)
{
measure.buffer = Marshal.StringToHGlobalUni(argv[0].ToUpper());
}
//If we are given no arguments convert to uppercase the string we recived with the input option
else
{
measure.buffer = Marshal.StringToHGlobalUni(measure.inputStr.ToUpper());
return Rainmeter.StringBuffer.Update(argv[0].ToUpper());
}
return measure.buffer;

// If we are given no arguments convert to uppercase the string we recived with the input option
return Rainmeter.StringBuffer.Update(measure.inputStr.ToUpper());
}

[DllExport]
public static IntPtr ToLower(IntPtr data, int argc,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 1)] string[] argv)
{
Measure measure = (Measure)data;
if (measure.buffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(measure.buffer);
measure.buffer = IntPtr.Zero;
}

//If we are given one or more arguments convert to uppercase the first one
if (argc > 0)
{
measure.buffer = Marshal.StringToHGlobalUni(argv[0].ToUpper());
}
//If we are given no arguments convert to uppercase the string we recived with the input option
else
{
measure.buffer = Marshal.StringToHGlobalUni(measure.inputStr.ToLower());
return Rainmeter.StringBuffer.Update(argv[0].ToUpper());
}
return measure.buffer;

return Rainmeter.StringBuffer.Update(measure.inputStr.ToLower());
}

[DllExport]
public static void Finalize(IntPtr data)
{
Measure measure = (Measure)data;
if (measure.buffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(measure.buffer);
}
GCHandle.FromIntPtr(data).Free();
}
}
Expand Down
22 changes: 1 addition & 21 deletions C#/PluginSystemVersion/PluginSystemVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,6 @@ internal string GetString()

public static class Plugin
{
static IntPtr StringBuffer = IntPtr.Zero;

[DllExport]
public static void Initialize(ref IntPtr data, IntPtr rm)
{
Expand All @@ -173,12 +171,6 @@ public static void Initialize(ref IntPtr data, IntPtr rm)
public static void Finalize(IntPtr data)
{
GCHandle.FromIntPtr(data).Free();

if (StringBuffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(StringBuffer);
StringBuffer = IntPtr.Zero;
}
}

[DllExport]
Expand All @@ -199,19 +191,7 @@ public static double Update(IntPtr data)
public static IntPtr GetString(IntPtr data)
{
Measure measure = (Measure)GCHandle.FromIntPtr(data).Target;
if (StringBuffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(StringBuffer);
StringBuffer = IntPtr.Zero;
}

string stringValue = measure.GetString();
if (stringValue != null)
{
StringBuffer = Marshal.StringToHGlobalUni(stringValue);
}

return StringBuffer;
return Rainmeter.StringBuffer.Update(measure.GetString());
}
}
}