dotnet / dotnet/samples

CustomHostClr Sample doesn't work with returning values

Open
#6,975 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
C#
Stars
3.7k
Forks
5.1k
Avg merge
9h 11m
Merged PRs (30d)
1

Description

## [CustomHostClr Sample doesn't work with returning values]

I worked through this sample core/hosting/src. There is a missing sample for invocation when some value retuned from the managed side via pre-defined buffer.
I tried to add this sample myself but it doesn't seem to work.

On the native side (in nativehost.cpp line ~190) added:

```
// Function pointer to managed delegate with non-default signature
typedef void (CORECLR_DELEGATE_CALLTYPE *custom_entry_point_returning_fn)(wchar_t const* someptr, wchar_t* out_res);
custom_entry_point_returning_fn custom_returning = nullptr;

// Custom delegate type
rc = load_assembly_and_get_function_pointer(
dotnetlib_path.c_str(),
dotnet_type,
STR("CustomEntryPointReturning") /*method_name*/,
STR("DotNetLib.Lib+CustomEntryPointReturningDelegate, DotNetLib") /*delegate_type_name*/,
nullptr,
(void**)&custom_returning);
assert(rc == 0 && custom_returning != nullptr && "Failure: load_assembly_and_get_function_pointer()");
wchar_t const* someptr = STR("some data");
wchar_t buffer[128]{STR("some init data")};
custom_returning(someptr, buffer);

std::wcout << STR("returned buffer: ") << buffer << std::endl;

```

In the Lib.cs I added:

```
public delegate void CustomEntryPointReturningDelegate(IntPtr someptr, StringBuilder res);
public static void CustomEntryPointReturning(IntPtr someptr, StringBuilder res)
{
string message = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? Marshal.PtrToStringUni(someptr)
: Marshal.PtrToStringUTF8(someptr);

Console.WriteLine($"Hello, world! from {nameof(CustomEntryPointReturning)} in {nameof(Lib)}");

Console.WriteLine($"Passed-in string: {message}");

Console.WriteLine($"the buffer on the managed side: {res.ToString()}");
res.Clear();
res.Append("some returned text");
Console.WriteLine($"the buffer on the managed side: {res.ToString()}");
}

```

It outputs:

```
Hello, world! from CustomEntryPointReturning in Lib
Passed-in string: some data
the buffer on the managed side: s
the buffer on the managed side: some returned text
returned buffer:

```

Please, add this kind of example I sketch above (with some fixes required) into the sample.

**UPDATE:**
To fix reported behaviour

On the native side (in nativehost.cpp line ~190) added:

```
// Function pointer to managed delegate with non-default signature
typedef void (CORECLR_DELEGATE_CALLTYPE *custom_entry_point_returning_fn)(wchar_t const* someptr, char* out_res);
custom_entry_point_returning_fn custom_returning = nullptr;

// Custom delegate type
rc = load_assembly_and_get_function_pointer(
dotnetlib_path.c_str(),
dotnet_type,
STR("CustomEntryPointReturning") /*method_name*/,
STR("DotNetLib.Lib+CustomEntryPointReturningDelegate, DotNetLib") /*delegate_type_name*/,
nullptr,
(void**)&custom_returning);
assert(rc == 0 && custom_returning != nullptr && "Failure: load_assembly_and_get_function_pointer()");
wchar_t const* someptr = STR("some data");
char buffer[128]{"some init data"};
custom_returning(someptr, buffer);

std::wcout << STR("returned buffer: ") << buffer << std::endl;

```

Note the change of type for out_res pointer from wchat_t to char. And then it works (the output is below):

```
Hello, world! from CustomEntryPointReturning in Lib
Passed-in string: some data
the buffer on the managed side: some init data
the buffer on the managed side: some returned text
returned buffer: some returned text

```

It's strange that marshaled back string is 8-bit instead of 16-bit. If you let me know I'll create issue in more relevant repo about this possible CLR marshaling bug.

---
#### Issue metadata

* Issue type: sample-update

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.