Closed SapientGuardian closed 4 years ago
Hello @SapientGuardian
std::cin
is not actually a variable (at least for ExVar context) and in general assumes working with streams.
ExVar was just designed for other purposes such as final data as variables or some other const data in memory.
That is,
00007FF844A06070 -> 00007ff8449db0d0 -> data
^^^^^^^^^^^^^^^^
final value at this pointer
See details in #7 and https://github.com/3F/DllExport/issues/24
Logic of the getVar above was based on getField + our Conari 'native' extension:
-> getField
v
-> -> provider
.Svc
.native(lpProcName)
.t(type)
.Raw.Type.FirstField;
Therefore it will return an wrong pointer because ExVar feature already calculated this as final data by jumping "forward".
I don't remember exactly but more like we don't have special logic for any streams and similar cases in 1.4. Although for 1.4 you can try at least this:
var cin = l.Svc.getProcAddr(l.Svc.procName("?cin@std@@3V?$basic_istream@DU?$char_traits@D@std@@@1@A", false));
// now a correct pointer to std::cin stream
I think we need a more elegant ~"Conari way".
But I still can't talk anything specific about some changes/new features/or some releases at least from me due to my health problems and more; However I can try to coordinate some work around my projects and their releases if someone be ready for something.
Thanks for using. Yours, -- Denis Kuzmin
FYI don't forget about aliases which are super useful for C++ (the case of #3). For example:
l.Aliases.Add("cin", "?cin@std@@3V?$basic_istream@DU?$char_traits@D@std@@@1@A");
then it could be like
_v1 = l.ExVar.DLR.cin<IntPtr>();
_v2 = l.ExVar.get<IntPtr>("cin");
// ...
l.ExVar.get<IntPtr>("class std::basic_istream<char,struct std::char_traits<char>> std::cin");
etc.
Thank you for your insights; the getProcAddr method you suggested works perfectly!
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
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: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 is0x00007ffe2a0cc110
, which the Visual Studio debugger tells me is the address ofstd::basic_istream<char,std::char_traits<char>>:: vbtable'
, not ofstd::basic_istream<char,std::char_traits<char>> std::cin
. Indeed, if I putstd::cout << &(std::cin);
in the C++ app, it outputs 00007FFE2A0F7200, which Visual Studio agrees is correct.If I force
00007FFE2A0F7200
into mycin
variable instead of getting it withgetVar
, the function executes correctly, prompting for user input and storing it innumber
.