Description
Calling a managed C++/CLI function with 17 or more parameters from a native C++ executable via IJW (It Just Works) interop throws an unhandled HRException at runtime. The same code works correctly on .NET 8 and works correctly on .NET 10 if the function has 16 or fewer parameters.
Reproduction Steps
- C++/CLI managed project (CppCliProject.dll) — Functions.hpp:
#pragma once
#include <cstdint>
struct IntWrapper
{
int Value;
};
class __declspec(dllexport) Functions
{
public:
int64_t static Sum17(const int& a0,
const IntWrapper& a1,
const IntWrapper& a2,
const IntWrapper& a3,
const IntWrapper& a4,
const IntWrapper& a5,
const IntWrapper& a6,
const IntWrapper& a7,
const IntWrapper& a8,
const IntWrapper& a9,
const IntWrapper& a10,
const IntWrapper& a11,
const IntWrapper& a12,
const IntWrapper& a13,
const IntWrapper& a14,
const IntWrapper& a15,
const IntWrapper& a16,
const int& a17);
};
function.cpp
#include "Functions.hpp"
int64_t Functions::Sum17(const int& a0,
const IntWrapper& a1,
const IntWrapper& a2,
const IntWrapper& a3,
const IntWrapper& a4,
const IntWrapper& a5,
const IntWrapper& a6,
const IntWrapper& a7,
const IntWrapper& a8,
const IntWrapper& a9,
const IntWrapper& a10,
const IntWrapper& a11,
const IntWrapper& a12,
const IntWrapper& a13,
const IntWrapper& a14,
const IntWrapper& a15,
const IntWrapper& a16,
const int& a17)
{
System::Console::WriteLine(System::Runtime::InteropServices::RuntimeInformation::FrameworkDescription);
System::Console::WriteLine(a1.Value);
System::Console::WriteLine(a2.Value);
return a1.Value + a2.Value + a3.Value + a4.Value + a5.Value + a6.Value + a7.Value + a8.Value + a9.Value + a10.Value
+ a11.Value + a12.Value + a13.Value + a14.Value + a15.Value + a16.Value + a17;
}
- Native C++ executable (ParametersCrashCppCli.exe) — main.cpp:
#include <iostream>
#include "../CppCliProject/Functions.hpp"
int main()
{
auto value = Functions::Sum17(0, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }, { 9 }, { 10 }, { 11 }, { 12 }, { 13 }, { 14 }, { 15 }, { 16 }, 17);
std::cout << value << std::endl;
}
ParametersCrashCppCli.zip
Expected behavior
The function executes normally and returns the sum of all 18 arguments (153).
Actual behavior
An unhandled HRException (Microsoft C++ exception) is thrown during the IJW native-to-managed thunk dispatch:
Exception thrown at 0x00007FFE757773FA in ParametersCrashCppCli.exe:
Microsoft C++ exception: HRException at memory location 0x0000008702CFEC38.
Callstack:
KernelBase.dll!00007ffe757773fa
ParametersCrashCppCli.exe!main [ParametersCrashCppCli.cpp @ line with Sum17 call]
ParametersCrashCppCli.exe!invoke_main
ParametersCrashCppCli.exe!__scrt_common_main_seh
Regression?
yes, works in .NET8
Known Workarounds
reduce number of parameters
Configuration
Environment
| Component |
Version |
| .NET Runtime |
10.0.5 |
coreclr.dll |
10.0.5 (C:\...\dotnet-sdk\shared\Microsoft.NETCore.App\10.0.5\) |
clrjit.dll |
10.0.5 (C:\...\dotnet-sdk\shared\Microsoft.NETCore.App\10.0.5\) |
Ijwhost.dll |
loaded from x64\Debug\Ijwhost.dll |
| MSVC toolset |
14.50.35717 |
| Visual Studio |
18 Professional |
| OS |
Windows (x64) |
| Architecture |
x64 |
| Configuration |
Debug |
Other information
No response
Description
Calling a managed C++/CLI function with 17 or more parameters from a native C++ executable via IJW (It Just Works) interop throws an unhandled HRException at runtime. The same code works correctly on .NET 8 and works correctly on .NET 10 if the function has 16 or fewer parameters.
Reproduction Steps
function.cpp
ParametersCrashCppCli.zip
Expected behavior
The function executes normally and returns the sum of all 18 arguments (153).
Actual behavior
An unhandled HRException (Microsoft C++ exception) is thrown during the IJW native-to-managed thunk dispatch:
Callstack:
Regression?
yes, works in .NET8
Known Workarounds
reduce number of parameters
Configuration
Environment
coreclr.dllC:\...\dotnet-sdk\shared\Microsoft.NETCore.App\10.0.5\)clrjit.dllC:\...\dotnet-sdk\shared\Microsoft.NETCore.App\10.0.5\)Ijwhost.dllx64\Debug\Ijwhost.dllOther information
No response