Description
Hello,
I have a C# function that is getting invoked from a C++ executable. In this function, I am attempting to do the literal equivalent of
int number;
std::cin >> number;
Obviously I could do something like number = int.Parse(Console.ReadLine())
, but in this case I really need to do exactly what C++ is doing (and besides, what fun would that be?). Leveraging a decompiler to get the exact mangled names, I came up with this code:
int number= 0;
using (var l = new ConariL(@"c:\windows\system32\MSVCP140.dll"))
{
var cin = l.ExVar.getVar<IntPtr>("?cin@std@@3V?$basic_istream@DU?$char_traits@D@std@@@1@A");
l.bind<FuncOut2<IntPtr, int, IntPtr>>("??5?$basic_istream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@AEAH@Z").Invoke(cin, out number);
}
The function binding works correctly, but it throws an access violation inside of the function because the address of cin
is incorrect. The intptr returned by getVar is 0x00007ffe2a0cc110
, which the Visual Studio debugger tells me is the address of std::basic_istream<char,std::char_traits<char>>:: vbtable'
, not of std::basic_istream<char,std::char_traits<char>> std::cin
. Indeed, if I put std::cout << &(std::cin);
in the C++ app, it outputs 00007FFE2A0F7200, which Visual Studio agrees is correct.
If I force 00007FFE2A0F7200
into my cin
variable instead of getting it with getVar
, the function executes correctly, prompting for user input and storing it in number
.