Skip to content

Commit

Permalink
.NET: Additional support for method args and more constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Apr 1, 2024
1 parent 3502c52 commit ca28d43
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 2 deletions.
3 changes: 3 additions & 0 deletions csharp-api/REFrameworkNET/Field.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include <reframework/API.hpp>

#include "TypeDefinition.hpp"

#pragma managed

namespace REFrameworkNET {
Expand All @@ -10,6 +12,7 @@ ref class TypeDefinition;
public ref class Field {
public:
Field(const reframework::API::Field* field) : m_field(field) {}
Field(::REFrameworkFieldHandle handle) : m_field(reinterpret_cast<const reframework::API::Field*>(handle)) {}

System::String^ GetName() {
return gcnew System::String(m_field->get_name());
Expand Down
9 changes: 9 additions & 0 deletions csharp-api/REFrameworkNET/ManagedObject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ public ref class ManagedObject : public System::Dynamic::DynamicObject, public S
}
}

// Double check if we really want to allow this
// We might be better off having a global managed object cache
// instead of AddRef'ing every time we create a new ManagedObject
ManagedObject(ManagedObject^ obj) : m_object(obj->m_object) {
if (m_object != nullptr) {
AddRef();
}
}

~ManagedObject() {
if (m_object != nullptr) {
Release();
Expand Down
42 changes: 40 additions & 2 deletions csharp-api/REFrameworkNET/Method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
#include "Field.hpp"

#include "API.hpp"
#include "VM.hpp"
#include "SystemString.hpp"

#include "Utility.hpp"

using namespace System;

namespace REFrameworkNET {
MethodHook^ Method::AddHook(bool ignore_jmp) {
return MethodHook::Create(this, ignore_jmp);
Expand Down Expand Up @@ -38,8 +42,34 @@ REFrameworkNET::InvokeRet^ Method::Invoke(System::Object^ obj, array<System::Obj
//args2[i] = args[i]->ptr();
const auto t = args[i]->GetType();

if (t == REFrameworkNET::ManagedObject::typeid) {
args2[i] = safe_cast<REFrameworkNET::ManagedObject^>(args[i])->Ptr();
if (t->IsSubclassOf(REFrameworkNET::IObject::typeid)) {
auto iobj = safe_cast<REFrameworkNET::IObject^>(args[i]);

if (iobj->IsProperObject()) {
args2[i] = iobj->Ptr();
} else if (t == REFrameworkNET::TypeDefinition::typeid) {
// TypeDefinitions are wrappers for System.RuntimeTypeHandle
// However there's basically no functions that actually take a System.RuntimeTypeHandle
// so we will just convert it to a System.Type.
if (auto td = iobj->GetTypeDefinition(); td != nullptr) {
if (auto rt = td->GetRuntimeType(); rt != nullptr) {
args2[i] = rt->Ptr();
} else {
System::Console::WriteLine("TypeDefinition has no runtime type @ arg " + i);
}
}
} else {
args2[i] = nullptr;
System::Console::WriteLine("Unknown IObject type passed to method invocation @ arg " + i);
}
} else if (t == System::String::typeid) {
auto createdStr = VM::CreateString(safe_cast<System::String^>(args[i]));

if (createdStr != nullptr) {
args2[i] = createdStr->Ptr();
} else {
System::Console::WriteLine("Error creating string @ arg " + i);
}
} else if (t == System::Boolean::typeid) {
bool v = System::Convert::ToBoolean(args[i]);
args2[i] = (void*)(intptr_t)v;
Expand Down Expand Up @@ -181,6 +211,14 @@ bool Method::HandleInvokeMember_Internal(System::Object^ obj, System::String^ me
result = gcnew REFrameworkNET::TypeDefinition((::REFrameworkTypeDefinitionHandle)tempResult->QWord);
break;
}
case "System.RuntimeMethodHandle"_fnv: {
result = gcnew REFrameworkNET::Method((::REFrameworkMethodHandle)tempResult->QWord);
break;
}
case "System.RuntimeFieldHandle"_fnv: {
result = gcnew REFrameworkNET::Field((::REFrameworkFieldHandle)tempResult->QWord);
break;
}
default:
result = tempResult;
break;
Expand Down
1 change: 1 addition & 0 deletions csharp-api/REFrameworkNET/Method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public ref class Method : public System::IEquatable<Method^>
{
public:
Method(reframework::API::Method* method) : m_method(method) {}
Method(::REFrameworkMethodHandle handle) : m_method(reinterpret_cast<reframework::API::Method*>(handle)) {}

void* GetRaw() {
return m_method;
Expand Down

0 comments on commit ca28d43

Please sign in to comment.