SharpSource
Short description:
SharpSource is a SourceMod extension which enables the developer to create extensions in C#. Like adding new native functions while using C#.
Status report:
This extension is currently in an early development stage, while the code is already available in order to encourage other people to participate in the development, binaries will be shipped when the extension will provide more functionality.
Currently the plugin loads managed (C#) code and loads managed assemblies, note how the arguments are all marshalled.
TODO:- Adjust and compliment (with helper functions) the exposed C++ interfaces for easy access
- Create a safe subplugin system
- Add IronRuby support
- Add IronPython support
DONE:- Access C++ interfaces from within C#
- Generate C++ wrapper classes with gccxml/a C# generator
- Support native function creation
Credits:
The CXXI Project - an awesome C++ bindings generator for C#
Bailoplan for such a great project
Code is available at
github
Some of the interfaces available in the C++ world are now available in the C# world.
I am continuing to add more and more, but I have to adjust them to make the look as native as possible.
A lot of the code is autogenerated, but the generated code needs a lot of adjustments.
Adding native functions from the C# world looks already quite awesome and easy to do:
PHP Code:
using System;
using AlliedMods;
using AlliedMods.SourceMod;
using AlliedMods.SourcePawn;
namespace TestSuite
{
public class InteropTests : IExt
{
static int tests = 0;
public InteropTests()
{
Core.ShareSys.AddNatives("test_addnative1", (IntPtr context, IntPtr arguments) => {
tests++;
return 1;
});
Core.ShareSys.AddNatives("test_addnative2", (IPluginContext context, int[] arguments) => {
tests++;
return 2;
});
Core.ShareSys.AddNatives(Core.Extension, typeof(InteropTests));
}
[SPMethod]
public static void test_addnative0()
{
}
[SPMethod("test_addnative3")]
public static int test_addnative3()
{
tests++;
return 3;
}
[SPMethod]
public static int test_addnative4()
{
tests++;
return 4;
}
[SPMethod]
public static int test_addnative5(int argument)
{
tests++;
if (argument != 42) {
Console.WriteLine("failed test_addnative5");
}
return 5;
}
[SPMethod]
public static int test_addnative6()
{
tests++;
return 42;
}
[SPMethod]
public static int test_addnative7(int i)
{
tests++;
return i;
}
[SPMethod]
public static void test_end(int count)
{
Console.WriteLine();
Console.WriteLine("tests executed {0}/{1}", tests, count);
Console.WriteLine();
}
[SPMethod]
public static void test_callback(Action<SPBuffer> callback, SPBuffer buffer, uint maxlength)
{
if (buffer.Get() != "HELLO WORLD") {
Console.WriteLine("FAILED");
}
buffer.Set(buffer.Get().ToLower(), maxlength);
callback(buffer);
}
}
}
PHP Code:
#include <sourcemod>
public Plugin:myinfo =
{
name = "SharpSource example plugin",
author = "Andrius Bentkus",
description = "SharpSource testing suite",
version = "0.0.1.0",
url = "no site available"
};
native test_addnative0();
native test_addnative1();
native test_addnative2();
native test_addnative3();
native test_addnative4();
native test_addnative5(i);
native test_addnative6();
native test_addnative7(i);
native test_end(i);
native test_callback(Function:func, String:buffer[], maxlength);
// new Function:callback = GetFunctionByName(GetMyHandle(), "callback_func");
public callback_func(String:str[])
{
assert(strcmp(str, "hello world") == 0);
}
public OnPluginStart()
{
assert(test_addnative0() == 0);
assert(test_addnative1() == 1);
assert(test_addnative2() == 2);
assert(test_addnative3() == 3);
assert(test_addnative4() == 4);
assert(test_addnative5(42) == 5);
assert(test_addnative6() == 42);
new i = 1234;
assert(test_addnative7(i) == i);
test_end(7);
new String:buffer[] = "HELLO WORLD";
test_callback(callback_func, buffer, sizeof(buffer));
}