Why does this code always print 0.000000
?
#98650
-
LibC.cs
test.cs
|
Beta Was this translation helpful? Give feedback.
Answered by
huoyaoyuan
Feb 19, 2024
Replies: 2 comments 6 replies
-
I believe you need to use using System;
using System.Runtime.InteropServices;
unsafe class Program
{
[DllImport("msvcrt.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern int wprintf(char* format, __arglist);
[DllImport("msvcrt.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern int printf(byte* format, __arglist);
static void Main(string[] args)
{
ReadOnlySpan<char> str = "%d %d %d %lf %lf %lf\n";
fixed (char* p = str)
wprintf(p, __arglist(1, 2, 3, 10.4, 23.5, 53.3));
ReadOnlySpan<byte> str2 = "%d %d %d %lf %lf %lf\n"u8;
fixed (byte* p = str2)
printf(p, __arglist(1, 2, 3, 10.4, 23.5, 53.3));
}
} Also note that you cannot use |
Beta Was this translation helpful? Give feedback.
1 reply
-
On win-x86, it correctly prints Looks like an interop bug. Sample disassembly: ; Method CSPlayground.Program:Main(System.String[]) (FullOpts)
G_M000_IG01: ;; offset=0x0000
push rbp
sub rsp, 48
vzeroupper
lea rbp, [rsp+0x30]
G_M000_IG02: ;; offset=0x000D
mov rcx, 0x28773E42ED0
mov bword ptr [rbp-0x08], rcx
vmovsd xmm1, qword ptr [reloc @RWD00]
mov rax, 0x7FF84D4BC890
G_M000_IG03: ;; offset=0x002D
call rax ; CSPlayground.Program:printf(ulong,double)
xor eax, eax
mov bword ptr [rbp-0x08], rax
cmp dword ptr [(reloc 0x7fff70fd505c)], 0
jne SHORT G_M000_IG05
G_M000_IG04: ;; offset=0x003E
add rsp, 48
pop rbp
ret
G_M000_IG05: ;; offset=0x0044
call CORINFO_HELP_POLL_GC
jmp SHORT G_M000_IG04
RWD00 dq 3FBF9A6B50B0F27Ch ; 0.12345
; Total bytes of code: 75 |
Beta Was this translation helpful? Give feedback.
5 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In short:
Varargs function must be defined as varargs P/Invoke to be used correctly:
Varargs is only supported on Windows x86/x64. For x86 it matches cdecl which only uses stack, but on x64 there's only fastcall. There is no way to correctly invoke
printf
on Unix or ARM.