@@ -18,6 +18,10 @@ We have the following goals related to interop code being used in CoreFX:
18
18
- This is both for good hygiene and to help keep platform-specific code
19
19
separated from platform-neutral code, which is important for maximizing
20
20
reusable code above PAL layers.
21
+ - Ensure maximal managed code reuse across different OS flavors which have
22
+ the same API but not the same ABI.
23
+ - This is the case for UNIX and addressing it is a work-in-progress (see issue
24
+ #2137 and section on "shims" below.)
21
25
22
26
## Approach
23
27
@@ -244,3 +248,43 @@ rather than the underlying integral type.
244
248
should be named with the most discoverable name possible; if that name
245
249
is a concept (e.g. Errors), it can be named using managed naming
246
250
guidelines.
251
+
252
+
253
+ ## UNIX shims
254
+
255
+ Often, various UNIX flavors offer the same API from the point-of-view of compatibility
256
+ with C/C++ source code, but they do not have the same ABI. e.g. Fields can be laid out
257
+ differently, constants can have different numeric values, etc. Even the exports can
258
+ be named differently.
259
+
260
+ This leaves us with a situation where we can't write portable P/Invoke declarations
261
+ that will work on all flavors, and writing separate declarations per flavor is quite
262
+ fragile and won't scale.
263
+
264
+ To address this, we're moving to a model where all UNIX interop from corefx starts with
265
+ a P/Invoke to a C++ lib written specifically for corefx. These libs -- System.* .Native.so
266
+ (aka "shims") -- are intended to be very thin layers over underlying platform libraries.
267
+ Generally, they are not there to add any significant abstraction, but to create a
268
+ stable ABI such that the same IL assembly can work across UNIX flavors.
269
+
270
+ At this time, these shims are compiled in the dotnet/coreclr repository under the corefx
271
+ folder. This is temporary (issue #2301 ) until we add necessary infrastructure to build them
272
+ in this repository.
273
+
274
+ Guidelines for shim C++ API:
275
+
276
+ - Keep them as "thin"/1:1 as possible.
277
+ - We want to write the majority of code in C#.
278
+ - Never skip the shim and P/Invoke directly to the underlying platform API. It's
279
+ easy to assume something is safe/guaranteed when it isn't.
280
+ - Don't cheat and take advantage of coincidental agreement between
281
+ one flavor's ABI and the shim's ABI.
282
+ - Use PascalCase and spell things out in a style closer to Win32 than libc.
283
+ - At first, it seemed that we'd want to use 1:1 names for the shims, but it
284
+ turns out there are many cases where being strictly 1:1 isn't practical. As such,
285
+ the libraries will end up looking more self-consistent if we give them their
286
+ own style with which to express themselves.
287
+ - Stick to data types which are guaranteed not to vary in size across flavors. (Pointers
288
+ and size_t variance across bitness is OK.)
289
+ - e.g. use int32_t, int64_t from stdint.h and not int, long.
290
+
0 commit comments