CustomHostClr Sample doesn't work with returning values
- 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
Assessment
This issue has not been assessed yet.