Mercurial > pub > dyncall > dyncall
comparison test/callback_plain_c++/test_main.cc @ 545:ca28e9e3c644
- test/callback_plain_c++, to test C++ non-trivial aggrs by value, as well as method callback handlers
- Changelog
author | Tassilo Philipp |
---|---|
date | Tue, 31 May 2022 18:35:06 +0200 |
parents | |
children | 214c4efc104f |
comparison
equal
deleted
inserted
replaced
544:111236b31c75 | 545:ca28e9e3c644 |
---|---|
1 /* | |
2 | |
3 Package: dyncall | |
4 Library: test | |
5 File: test/callback_plain_c++/test_main.c | |
6 Description: | |
7 | |
8 Tests only C++ specifics: | |
9 - method callback handlers (= standard dyncallback handler, but testing | |
10 calling convention mode setting and hidden this ptr) | |
11 - calling functions or methods that take/return non-trivial C++ aggregates | |
12 | |
13 License: | |
14 | |
15 Copyright (c) 2022 Tassilo Philipp <tphilipp@potion-studios.com> | |
16 | |
17 Permission to use, copy, modify, and distribute this software for any | |
18 purpose with or without fee is hereby granted, provided that the above | |
19 copyright notice and this permission notice appear in all copies. | |
20 | |
21 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
22 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
23 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
24 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
25 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
26 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
27 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
28 | |
29 */ | |
30 | |
31 #include "../../dyncallback/dyncall_callback.h" | |
32 #include "../common/platformInit.h" | |
33 #include "../common/platformInit.c" /* Impl. for functions only used in this translation unit */ | |
34 | |
35 | |
36 #if defined(DC__Feature_AggrByVal) | |
37 struct Triv { | |
38 float t; | |
39 }; | |
40 | |
41 struct NonTriv { | |
42 int i, j; | |
43 NonTriv(int a, int b) : i(a),j(b) { } | |
44 NonTriv(const NonTriv& rhs) { static int a=13, b=37; i = a++; j = b++; } | |
45 }; | |
46 | |
47 | |
48 char cbNonTrivAggrArgHandler(DCCallback* cb, DCArgs* args, DCValue* result, void* userdata) | |
49 { | |
50 int* ud = (int*)userdata; | |
51 int arg1; | |
52 NonTriv arg2(0, 0); | |
53 NonTriv arg3(0, 0); | |
54 Triv arg4; | |
55 double arg5; | |
56 | |
57 printf("reached callback\n"); | |
58 printf("userdata: %d\n", *ud); | |
59 | |
60 // the non-triv arg4 test basically assures that the aggr description list is | |
61 // respected (with first two being NULL as non-trivial aggrs) | |
62 arg1 = dcbArgInt(args); printf("1st argument: %d\n", arg1); | |
63 arg2 = *(NonTriv*)dcbArgAggr(args, NULL); printf("2nd argument: %d %d\n", arg2.i, arg2.j); | |
64 arg3 = *(NonTriv*)dcbArgAggr(args, NULL); printf("3nd argument: %d %d\n", arg3.i, arg3.j); | |
65 dcbArgAggr(args, (DCpointer)&arg4); printf("4th argument: %f\n", arg4.t); | |
66 arg5 = dcbArgDouble(args); printf("5th argument: %f\n", arg5); | |
67 | |
68 // the non-triv aggregate members are 14, 38 and 15, 39, respectively, b/c of | |
69 // copy-ctor call on *passing* them to this handler (not b/c of assignment | |
70 // operator, above); see below on where 13 and 37 are initialized | |
71 result->d = *ud + arg1 + arg2.i + arg2.j + arg3.i + arg3.j + arg4.t + arg5; | |
72 return 'd'; | |
73 } | |
74 | |
75 | |
76 int testNonTrivAggrArgsCallback() | |
77 { | |
78 DCCallback* cb; | |
79 Triv t = { 1.75f }; | |
80 NonTriv a(1, 2); | |
81 NonTriv b(a); // this sets NonTriv's statics a = 13 and b = 37 | |
82 | |
83 int ret = 1; | |
84 double result = 0; | |
85 int userdata = 1337; | |
86 | |
87 DCaggr *triv_aggr = dcNewAggr(1, sizeof(t)); | |
88 dcAggrField(triv_aggr, DC_SIGCHAR_FLOAT, offsetof(Triv, t), 1); | |
89 dcCloseAggr(triv_aggr); | |
90 | |
91 DCaggr *aggrs[3] = { NULL, NULL, triv_aggr }; // NULL b/c non-trivial aggrs, see manpage | |
92 | |
93 cb = dcbNewCallback2("iAAAd)d", &cbNonTrivAggrArgHandler, &userdata, aggrs); | |
94 | |
95 result = ((double(*)(int, NonTriv, NonTriv, Triv, double))cb)(123, a, b, t, 4.5); | |
96 dcbFreeCallback(cb); | |
97 | |
98 printf("successfully returned from callback\n"); | |
99 printf("return value (should be 1572.25): %f\n", result); | |
100 | |
101 ret = result == 1572.25 && ret; | |
102 | |
103 return ret; | |
104 } | |
105 | |
106 | |
107 | |
108 char cbNonTrivAggrReturnHandler(DCCallback* cb, DCArgs* args, DCValue* result, void* userdata) | |
109 { | |
110 printf("reached callback\n"); | |
111 dcbReturnAggr(args, result, NULL); // this sets result->p to the non-triv aggr space allocated by the calling convention | |
112 *(NonTriv*)result->p = NonTriv(1, 3); // explicit non-copy ctor and assignment operator, so not using NonTriv's statics a and b | |
113 | |
114 return 'A'; | |
115 } | |
116 | |
117 | |
118 int testNonTrivAggrReturnCallback() | |
119 { | |
120 int ret = 1; | |
121 | |
122 { | |
123 DCCallback* cb; | |
124 DCaggr *aggrs[1] = { NULL }; // one non-triv aggr | |
125 cb = dcbNewCallback2(")A", &cbNonTrivAggrReturnHandler, NULL, aggrs); | |
126 | |
127 NonTriv result = ((NonTriv(*)())cb)(); | |
128 | |
129 dcbFreeCallback(cb); | |
130 | |
131 printf("successfully returned from callback\n"); | |
132 printf("return value (should be %d %d): %d %d\n", 1, 3, result.i, result.j); | |
133 | |
134 ret = result.i == 1 && result.j == 3 && ret; | |
135 } | |
136 | |
137 return ret; | |
138 } | |
139 #endif | |
140 | |
141 | |
142 int main() | |
143 { | |
144 int result = 1; | |
145 | |
146 dcTest_initPlatform(); | |
147 | |
148 #if defined(DC__Feature_AggrByVal) | |
149 result = testNonTrivAggrArgsCallback() && result; | |
150 result = testNonTrivAggrReturnCallback() && result; | |
151 #endif | |
152 | |
153 printf("result: callback_plain_c++: %d\n", result); | |
154 | |
155 dcTest_deInitPlatform(); | |
156 | |
157 return !result; | |
158 } | |
159 |