Just a progress report. It's going well! I have found ways to make more things work.
1. Move more C binding code to standard hpp file ====================================== The interface_file.flx now #include file.hpp, I have modified the compiler so file.hpp is more suitable. This guarantees that any types in the C code of the interface refer to the actual types Felix generated for that file. In fact the C code part of the C binding code available to the client is the identical file used when C++ compiling the library. The code is NOT quite identical however because of a macro. Exports are marked FLX_EXTERN_file In the library, this is defined to FLX_EXPORT prior to #include. In the interface, it's defined as FLX_IMPORT prior to #include. Note that the current system leaves these both blank on Unix systems, on Windows you get _dll_export and _dll_import for dynamic linkage. However this will change because gcc and clang both have visibility attributes now. Just to remind you there are 3 levels of visibility: internal linkage (static function) -- visible in translation unit only external linkage (extern function) -- visible in static linkage only export linkage -- visible in DLLs too Older gcc/clang compilers only provided export linkage for extern. This means every extern symbol in a fully linked shared library was visible to clients of the library (eg for dlsym()). These compilers now try to make it possible to do what Windows has always required: hide all symbols not marked for dynamic linkage visibility. 2. Support export struct ================== Although not implemented I have tested this by hand. The idea is you can export struct X { x:int; }; in a library and the interface will say: cstruct X { x:int; }; This allows type X to be used as a structure, that is, it supports not only passing values of that type, etc, but also construction and field access. The cstruct construction mandates that the name of the underlying C structure is X. exporting a type like export type (X) as "X"; will construct a typedef at global scope: typedef ::flxusr::file::X_mangled_name X; which the C struct construction can then bind to. 3. By accident, list works =================== For some reason I don't fully understand, a list is represented by a void*. Since list of int, for example, is shared via the standard library, lists can be passed back and forward across client/library boundaries. It's not clear other union types will work, but possibly most they will because the C representation is invariant. One case that will not work is the simplest: union X = C of Y; Felix makes the representation just the representation of Y, so it's safe to use a uni-union .. i.e. a union with only one constructor .. without any performance loss. however other more complex unions are either standard types that fix into a machine word, tagged pointers, of a _uctor_ data type which is shared. Just so you grok the issue again: Felix synthesises arbitrary indeterminate C++ names for some structural types like tuples. For example the C++ type of int * double in one compilation will not be the same struct in another. Of course the layout will be the same. This means that the interface for a function accepting a tuple argument will have an argument of type generated when the library C++ code is generated, which the client cannot know. If we export this type: export type (int * double) as "intdouble"; what we get is: typedef ::flxusr::file::some_weird_mangled_name intdouble; So now, we can use that type, but only as an abstract type! If in our Felix client we try to pass (1, 2.3) to the function, the C++ type will be: ::flxusr::client::some_other_weird_name which is not the same type at all, and the C++ compiler will barf. Indeed, although layout compatible the two versions of the tuple are defined in both the client and library. But the exported abstract type allows copying, but it will not allow field access. You would have to write a cast (in Felix) to cast int * double to intdouble. 4. Exporting a cstruct? ================= The "right" way to do share a C struct is a Felix include file which (a) defines the cstruct and (b) ensures the C definition is available If you try to export a cstruct, then two interfaces exporting it would get the same Felix name defined, causing an error. Of course this would happen with a struct too. The difference is, a struct *defines* a struct, and so should not be defined twice. So when you export it the interface has a cstruct binding to it which can be shared by including the interface. Include files in Felix only get included once. Two distinct files defining the same cstruct can be included twice. There is an exception to this rule, where the cstruct in the library is considered a defining specification. In that case the cstruct can be exported into the interface, and is the sole binding used elsewhere. Exporting a cstruct is tricky because the "requirements" that force the C definition of the struct have to be exported too. -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language