Skip to content

Commit 3913a97

Browse files
committed
using approach with dummy struct for va_args
1 parent 7919acd commit 3913a97

File tree

2 files changed

+3
-43
lines changed

2 files changed

+3
-43
lines changed

examples/c_ffi_call/value_ffi.c

-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ static int _val_to_ffi_type(metac_entry_t * p_entry, metac_flag_t variadic, ffi_
121121
return -ENOMEM;
122122
}
123123
#if __linux__
124-
va_list x;
125124
p_ffi_type->type = FFI_TYPE_STRUCT;
126125
p_ffi_type->size = sizeof(void*);
127126
p_ffi_type->alignment = p_ffi_type->size;

modules/metac-reflect-gen/templates/_struct_type.tpl

+3-42
Original file line numberDiff line numberDiff line change
@@ -7,51 +7,12 @@
77
{{- $declaraion := false -}}
88
{{- with $v.ByteSize -}}
99
{{- $sz := toJson . }}
10-
// size {{ $sz }}
10+
struct _dummy_{{ $i }} { char _data_[ {{ $sz }} ]; };
1111
static metac_flag_t {{ $i }}_va_arg(struct va_list_container *p_va_list_container, void * buf) {
1212
if (p_va_list_container != NULL && buf != NULL) {
13-
{{- /*
14-
15-
This code is done this way in order to avoid an issue faced with Windows:
16-
if the structure has size 1,2,4 or 8 (potentially 16 for some platforms)
17-
va_arg(p_va_list_container->parameters, char[<size>]) just fails.
18-
but it works for other sizes.
19-
Also it workes ok for Linux and Mac. for now only Windows has this issue.
20-
the WA demonstrated here works ok for our tests.
21-
22-
In general it appears that va_list is very specific to platform
23-
and has many issues when you try to use it for structures (not pointers).
24-
*/ -}}
25-
{{- if eq "1" $sz }}
26-
uint8_t data = va_arg(p_va_list_container->parameters, int);
27-
memcpy(buf, &data, {{ . }});
13+
struct _dummy_{{ $i }} v = va_arg(p_va_list_container->parameters, struct _dummy_{{ $i }});
14+
memcpy(buf, &v, {{$sz}});
2815
return 1;
29-
{{- else if eq "2" $sz }}
30-
uint16_t data = va_arg(p_va_list_container->parameters, int);
31-
memcpy(buf, &data, {{ . }});
32-
return 1;
33-
{{- else if eq "4" $sz }}
34-
uint32_t data = va_arg(p_va_list_container->parameters, uint32_t);
35-
memcpy(buf, &data, {{ . }});
36-
return 1;
37-
{{- else if eq "8" $sz }}
38-
uint64_t data = va_arg(p_va_list_container->parameters, uint64_t);
39-
memcpy(buf, &data, {{ . }});
40-
return 1;
41-
{{- else }}
42-
long long data;
43-
if (sizeof(data) == {{ . }}) {
44-
data = va_arg(p_va_list_container->parameters, long long);
45-
memcpy(buf, &data, {{ . }});
46-
return 1;
47-
}
48-
void * p = (void*) va_arg(p_va_list_container->parameters, char[{{ . }}]);
49-
if (p == NULL) {
50-
return 0;
51-
}
52-
memcpy(buf, p, {{ . }});
53-
return 1;
54-
{{- end }}
5516
}
5617
return 0;
5718
}

0 commit comments

Comments
 (0)