Can't find a way to generate a function that allocates memory
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 35/100
Research direction
Start from the generator path that handles CS_OUT parameters and the code that creates temporary result variables; the issue includes the C++ declaration, C# setup, and generated output to reproduce the problem. Done means pointer-to-pointer out parameters are marshalled correctly and generated local names remain unique so the output compiles.
Written by the indexing model from the issue text.
Description
Brief Description
I couldn't find a way to setup the generator so it correctly generates a function that allocates the memory and returns it as an out parameter.
OS: Windows
Used headers
#define CS_OUT
typedef struct test_struct_t test_struct_t;
typedef struct test_pool_t test_pool_t;
void create_test_struct(CS_OUT test_struct_t** result, test_pool_t* pool);
The function create_test_struct allocates a new test_struct_t from the pool, and returns pointer to this struct to the caller -- so result is a pointer to a pointer.
Used settings
Target: MSVC (I think)
public void Setup(Driver driver)
{
driver.Options.GeneratorKind = GeneratorKind.CSharp;
var module = driver.Options.AddModule("TestModule");
module.IncludeDirs.Add(Environment.CurrentDirectory);
module.Headers.Add("TestHeader.h");
}
public void SetupPasses(Driver driver)
{
driver.AddTranslationUnitPass(new CheckMacroPass());
}
Stack trace or incompilable generated code
public unsafe partial class TestHeader
{
public partial struct __Internal
{
[SuppressUnmanagedCodeSecurity]
[DllImport("TestModule", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="?create_test_struct@@YAXPEAPEAUtest_struct_t@@PEAUtest_pool_t@@@Z")]
internal static extern void CreateTestStruct(global::System.IntPtr result, global::System.IntPtr pool);
}
public static void CreateTestStruct(out global::TestModule.TestStructT result, out global::TestModule.TestPoolT pool)
{
result = new global::TestModule.TestStructT();
var __arg0 = ReferenceEquals(result, null) ? global::System.IntPtr.Zero : result.__Instance;
pool = new global::TestModule.TestPoolT();
var __arg1 = ReferenceEquals(pool, null) ? global::System.IntPtr.Zero : pool.__Instance;
__Internal.CreateTestStruct(__arg0, __arg1);
global::TestModule.TestStructT __result0;
if (__arg0 == IntPtr.Zero) __result0 = null;
else if (global::TestModule.TestStructT.NativeToManagedMap.ContainsKey(__arg0))
__result0 = (global::TestModule.TestStructT) global::TestModule.TestStructT.NativeToManagedMap[__arg0];
else __result0 = global::TestModule.TestStructT.__CreateInstance(__arg0);
result = __result0;
global::TestModule.TestPoolT __result0;
if (__arg1 == IntPtr.Zero) __result0 = null;
else if (global::TestModule.TestPoolT.NativeToManagedMap.ContainsKey(__arg1))
__result0 = (global::TestModule.TestPoolT) global::TestModule.TestPoolT.NativeToManagedMap[__arg1];
else __result0 = global::TestModule.TestPoolT.__CreateInstance(__arg1);
pool = __result0;
}
}
The problem with this code is that it doesn't treat the result parameter as a pointer to pointer, e.g. an out parameter of the native function. So it passes it to NativeToManagedMap and __CreateInstance as is instead of dereferencing it first.
This code is also incompilable because of this:
global::TestModule.TestStructT __result0;
if (__arg0 == IntPtr.Zero) __result0 = null;
...
result = __result0;
global::TestModule.TestPoolT __result0;
if (__arg1 == IntPtr.Zero) __result0 = null;
...
pool = __result0;
In this case, two variables with the same name __result0 are declared. This of course leads to a compilation error. The second variable should have been called __result1 here.
- Dominant language
- C#
- Stars
- 3.4k
- Forks
- 541
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from mono/CppSharp
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
-
Difficulty 4/5 3-5 days Newbie friendliness 45/100
-
How to get started Open
Difficulty 3/5 1-2 days Newbie friendliness 38/100
-
Difficulty 4/5 3-5 days Newbie friendliness 25/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
:watch: Not Triaged 11.0 fundamentals/subsvc
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
dotnet/AspNetCore.Docs#37699 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SubtitleEdit/subtitleedit#15108 · 1 comment ·
-
area/docs-content Bug pulumi/docs
Difficulty 1/5 1-3 hours Newbie friendliness 94/100
-
agentic-workflows untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 76/100