I was reading about the language vala and that it compiles to Ansi C code. However I also saw it supports generics like Java or Rust. Now my question is how this is compiled to C code? If I have a gerneric class or function, what kind of C code is generated to simulate the generic behavior?
Vala generics are based on gpointer and GType.
You can only specialize a Generic class with a pointer based type parameter.
class MyClass<T> {
public T val;
}
public static int main (string[] args) {
// This wouldn't compile!
// var il = new Gee.ArrayList<int> ();
var il = new Gee.ArrayList<int?> ();
var dl = new Gee.ArrayList<double?> ();
il.add (5);
dl.add (3.0);
var im = new MyClass<int?>();
im.val = 5;
var dm = new MyClass<double?>();
dm.val = 3.0;
var lm = new MyClass< Gee.List<int?> > ();
lm.val = il;
return 0;
}
You can check the generated code yourself with the -C parameter:
valac -C Main.vala --pkg gee-0.8
This will generate a main.c file. If you read it carefully you will see there is only one struct for MyClass (plus some additional helper structs that are needed for GObject based classes) that has a member gpointer val, it also has a GType t_type as well as a t_dup_func and a t_destroy_func.
struct _MyClass {
// ...
gpointer val;
};
struct _MyClassPrivate {
GType t_type;
GBoxedCopyFunc t_dup_func;
GDestroyNotify t_destroy_func;
};
To ensure the correct type is passed in GLib type checking is performed. This makes Vala generics type safe (partially at compile time and partially at runtime).
This is in contrast with C++ templates which are expanded at compile time. So it is closer to C# generics than to classic C++ templates.
I wrote "partially at compile time" because the Vala compiler is smart enough to omit the type check in the C code when it knows that the assignment will always be correct.
Also Vala generated C code is meant to be easily consumable for other programming languages that have GLib bindings (like C, Python, C++, GJS, etc.)
Related
EDIT:
I think the version is known at run-time instead of compile-time so I'm not able to add it as a compile option to the gcc cmd. Which is why I have to support both versions based on whatever version the hardware reports back.
So I'm dealing with firmware where I am required to support multiple definitions for versions of the same C struct. We created our own header file as defined by the interface documentation of a memory controller based on the vendor's C struct definition.
// For simplicity lets pretend that this is the struct for version 1
typedef struct __attribute__((packed)) ver1 {
int x;
int y;
} ver1;
I also have an existing API that uses this interface already that needs to be replaced by some sort of class wrapper (I believe), or a wrapper that plays well with the existing API.
void function_call(ver1 v1);
Only one instance (ver 1 or ver 2) of the struct can exist at any time
ver 1 for a certain fw version, and ver 2 after a certain fw version
ver2 is my extended version of ver1, I am naming it as ver2 for the hope of using some sort of factory to select the right C-style struct.
typedef struct __attribute__((packed)) ver2 {
int x;
int y;
int w; // new
int z; // new
} ver2;
Before creating a ver 2 I was looking into options such as the decorator or adaptor design pattern I could try a fancy CRTP template style I found on Hands-On Design Patterns but for simplicity, I'll illustrate with this scheme where I could possibly "add-on" to ver1:
struct ver2 : public ver1 {
int w;
int z;
}
But then I learned that C++ doesn't guarantee the same class layout
C struct Inheritance vs C++ POD struct Inheritance
and potential alignment issues (I'm not too familiar with it) so I don't think it is a real option for me to use.
I found this example on stackoverflow but I don't like the idea of adding include headers in the struct How to handle conflicting struct definitions in a C application.
There is a similar example here using a similar base class
C++ design for multiple versions of same interface (enumerations / structures in header files) which I don't think I can even use due to inheritance impact on the class layout.
Unless there is a valid reason to use the techniques of the links above, I was considering a wrapper class that returns the right version based on a selector. First I'll define a free function to leverage this.
int get_fw_version(int target);
I'm working on C++11 so I'm limited on auto return type deduction and below is just some draft code I'm trying to think up, not complete, doesn't compile, just illustrating my thought process. I haven't considered composition yet since IDK how that will quite work. Looking for ideas.
int main() {
// Roughly how I would like to use it...
const int fw_ver = get_fw_version(target);
auto ver_inst = ver_factory(fw_ver);
function_call( ver_inst.get_data() );
return 0;
}
I am not sure if I can do this without polymorphism where the base class gets ver1 and but the derived class has ver2.
Rough idea where I am at, I tried doing CRTP but I hit the problem that the base class needs to be a template and I can't use a heterogeneous base type (e.g. shared_ptr). Trying the non-CRTP way IDK how to set up the abstract base class with the get_data() method. Without the compiler complains saying that the base doesn't have a get_data method, which, makes sense
// I can't figure out how to add T get_data() here without adding a template param. This base function is really to delegate common member methods and trying to keep a common base for polymorphism.
class base {
virtual ~base() = 0;
// ?? get_data() = 0 or some other method
};
class ver1_derived : public base
{
ver1 data;
public:
ver1_derived() = default;
ver1 get_data() {
return data;
}
};
class ver2_derived : public base
{
ver2 data;
public:
ver2_derived() = default;
ver2 get_data() {
return data;
}
};
// should be using unique_ptr but I can't at work....
shared_ptr<base> ver_factory(const int fw_ver) {
if(fw_ver <= 1)
return make_shared<ver1_derived>();
return make_shared<ver2_derived>();
}
I ended up giving up on an inheritance schemed and ended up taking two different code paths based on the template type.
So
if(fw_ver <= 1)
function_call<ver1>();
} else {
function_call<ver2>();
}
What is the intention to set handle to an object as pointer-to pointer but not pointer? Like following code:
FT_Library library;
FT_Error error = FT_Init_FreeType( &library );
where
typedef struct FT_LibraryRec_ *FT_Library
so &library is a FT_LIBraryRec_ handle of type FT_LIBraryRec_**
It's a way to emulate pass by reference in C, which otherwise only have pass by value.
The 'C' library function FT_Init_FreeType has two outputs, the error code and/or the library handle (which is a pointer).
In C++ we'd more naturally either:
return an object which encapsulated the success or failure of the call and the library handle, or
return one output - the library handle, and throw an exception on failure.
C APIs are generally not implemented this way.
It is not unusual for a C Library function to return a success code, and to be passed the addresses of in/out variables to be conditionally mutated, as per the case above.
The approach hides implementation. It speeds up compilation of your code. It allows to upgrade data structures used by the library without breaking existing code that uses them. Finally, it makes sure the address of that object never changes, and that you don’t copy these objects.
Here’s how the version with a single pointer might be implemented:
struct FT_Struct
{
// Some fields/properties go here, e.g.
int field1;
char* field2;
}
FT_Error Init( FT_Struct* p )
{
p->field1 = 11;
p->field2 = malloc( 100 );
if( nullptr == p->field2 )
return E_OUTOFMEMORY;
return S_OK;
}
Or C++ equivalent, without any pointers:
class FT_Struct
{
int field1;
std::vector<char> field2;
public:
FT_Struct() :
field1( 11 )
{
field2.resize( 100 );
}
};
As a user of the library, you have to include struct/class FT_Struct definition. Libraries can be very complex so this will slow down compilation of your code.
If the library is dynamic i.e. *.dll on windows, *.so on linux or *.dylib on osx, you upgrade the library and if the new version changes memory layout of the struct/class, old applications will crash.
Because of the way C++ works, objects are passed by value, i.e. you normally expect them to be movable and copiable, which is not necessarily what library author wants to support.
Now consider the following function instead:
FT_Error Init( FT_Struct** pp )
{
try
{
*pp = new FT_Struct();
return S_OK;
}
catch( std::exception& ex )
{
return E_FAIL;
}
}
As a user of the library, you no longer need to know what’s inside FT_Struct or even what size it is. You don’t need to #include the implementation details, i.e. compilation will be faster.
This plays nicely with dynamic libraries, library author can change memory layout however they please, as long as the C API is stable, old apps will continue to work.
The API guarantees you won’t copy or move the values, you can’t copy structures of unknown lengths.
I'm new at C, so sorry for my lack of knowledge (my C-book here is really massive :)
I would like to extend a shared library (libcustomer.so) with closed source, but public known api.
Is something like this possible?
rename libcustomer.so to liboldcustomer.so
create an extended shared library libcustomer.so (so others implicitly use the extended one)
link liboldcustomer.so into my extended libcustomer.so via -loldcustomer
forward any not extra-implemented methods directly to the old "liboldcustomer.so"
I don't think it would work that way (the name is compiled into the .so, isn't it?).
But what's the alternative?
For #4: is there a general way to do this, or do I have to write a method named like the old one and forward the call (how?)?
Because the original libcustomer.so (=liboldcustomer.so) can change from time to time, all that stuff should work dynamically.
For security reasons, our system has no LD_PRELOAD (otherwise I would take that :( ).
Think about extended validation-checks & some better NPE-handlings.
Thanks in advance for your help!
EDIT:
I'm just implementing my extension as shown in the answer, but I have one unhandled case at the moment:
How can I "proxy" the structs from the extended library?
For example I have this:
customer.h:
struct customer;
customer.c:
struct customer {
int children:1;
int age;
struct house *house_config;
};
Now, in my customer-extension.c I am writing all the public methods form customer.c, but how do I "pass-thru" the structs?
Many thanks for your time & help!
So you have OldLib with
void func1();
int func2();
... etc
The step 4 might look like creating another library with some static initialization.
Create NewLib with contents:
void your_func1();
void (*old_func1_ptr)() = NULL;
int (*old_func2_ptr)() = NULL;
void func1()
{
// in case you don't have static initializers, implement lazy loading
if(!old_func1_ptr)
{
void* lib = dlopen("OldLibFileName.so", RTLD_NOW);
old_func1_ptr = dlsym(lib, "func1");
}
old_func1_ptr();
}
int func2()
{
return old_func2_ptr();
}
// gcc extension, static initializer - will be called on .so's load
// If this is not supported, then you should call this function
// manually after loading the NewLib.so in your program.
// If the user of OldLib.so is not _your_ program,
// then implement lazy-loading in func1, func2 etc. - check function pointers for being NULL
// and do the dlopen/dlsym calls there.
__attribute__((constructor))
void static_global_init()
{
// use dlfcn.h
void* lib = dlopen("OldLibFileName.so", RTLD_NOW);
old_func1_ptr = dlsym(lib, "func1");
...
}
The static_global_init and all the func_ptr's can be autogenerated if you have some description of the old API. After the NewLib is created, you certainly can replace the OldLib.
Is there an mechanism or trick to run a function when a program loads?
What I'm trying to achieve...
void foo(void)
{
}
register_function(foo);
but obviously register_function won't run.
so a trick in C++ is to use initialization to make a function run
something like
int throwaway = register_function(foo);
but that doesn't work in C. So I'm looking for a way around this using standard C (nothing platform / compiler specific )
If you are using GCC, you can do this with a constructor function attribute, eg:
#include <stdio.h>
void foo() __attribute__((constructor));
void foo() {
printf("Hello, world!\n");
}
int main() { return 0; }
There is no portable way to do this in C, however.
If you don't mind messing with your build system, though, you have more options. For example, you can:
#define CONSTRUCTOR_METHOD(methodname) /* null definition */
CONSTRUCTOR_METHOD(foo)
Now write a build script to search for instances of CONSTRUCTOR_METHOD, and paste a sequence of calls to them into a function in a generated .c file. Invoke the generated function at the start of main().
Standard C does not support such an operation. If you don't wish to use compiler specific features to do this, then your next best bet might be to create a global static flag that is initialized to false. Then whenever someone invokes one of your operations that require the function pointer to be registered, you check that flag. If it is false you register the function then set the flag to true. Subsequent calls then won't have to perform the registration. This is similar to the lazy instantiation used in the OO Singleton design pattern.
There is no standard way of doing this although gcc provides a constructor attribute for functions.
The usual way of ensuring some pre-setup has been done (other than a simple variable initialization to a compile time value) is to make sure that all functions requiring that pre-setup. In other words, something like:
static int initialized = 0;
static int x;
int returnX (void) {
if (!initialized) {
x = complicatedFunction();
initialized = 1;
}
return x;
}
This is best done in a separate library since it insulates you from the implementation.
I am writing an Objective-C class but it uses an API written in C. This is mostly fine as mixing C calls with Objective-C calls causes few problems.
However one of the API call requires a call back method (example):
success = CFHostSetClient(host, MyCFHostClientCallBack, &context);
Where MyCFHostClientCallBack is a C function defined like this:
static void MyCFHostClientCallBack(CFHostRef host, CFHostInfoType typeInfo, const CFStreamError *error, void *info);
Can/How do I call an Objective-C method in place of this?
Can/Should I mix C functions with my Objective-C calls?
How do I mix C functions with Objective-C methods?
Mixing C and Objective-C methods and function is possible, here is a simple example that uses the SQLite API within an iPhone App: (course site)
Download the Zip file (09_MySQLiteTableView.zip)
C functions need to be declared outside of the #implementation in an Objective-C (.m) file.
int MyCFunction(int num, void *data)
{
//code here...
}
#implementation
- (void)MyObjectiveCMethod:(int)number withData:(NSData *)data
{
//code here
}
#end
Because the C function is outside of the #implementation it cannot call methods like
[self doSomething]
and has no access to ivars.
This can be worked around as long as the call-back function takes a userInfo or context type parameter, normally of type void*. This can be used to send any Objective-C object to the C function.
As in the sample code, this can be manipulated with normal Objective-C operations.
In addition please read this answer: Mixing C functions in an Objective-C class
To call Objective-C code from a C callback I would use something like:
void * refToSelf;
int cCallback()
{
[refToSelf someMethod:someArg];
}
#implementation SomeClass
- (id) init
{
self = [super init];
refToSelf = self;
}
- (void) someMethod:(int) someArg
{
}
Can/How do I call an Objective-C method in place of this?
You cannot.
Can/Should I mix C function in with my Objective-C call?
Yes. Write a C function and use that as the callback to the CF function.
How do I mix C function with Objective-C methods?
You can set self as the info pointer in your context structure. That will be passed to the callback. Then, in the callback, cast the info pointer back to id:
MyClass *self = (id)info;
You can then send self messages. You still can't directly access instance variables, though, since a C function is outside of the #implementation section. You'll have to make them properties. You can do this with a class extension. (Contrary to what that document says, you would not declare the extension inside #implementation, but in the same file with it, generally right above it.)
What I've always found helpful in this situation is to make an Obj-C wrapper on top of the C API. Implement what you need to using C functions, and build an Objective-C class (or two) on top of it, so that's all the outside world will see. For example, in the case of a callback like this, you might make a C function that calls Obj-C delegate methods on other objects.
.m call function inside .c:
CrifanLib.h
#ifndef CrifanLib_h
#define CrifanLib_h
#include <stdio.h>
void fileModeToStr(mode_t mode, char * modeStrBuf);
#endif /* CrifanLib_h */
CrifanLib.c
#include "CrifanLib.h"
#include <stdbool.h>
void fileModeToStr(mode_t mode, char * modeStrBuf) {
// buf must have at least 10 bytes
const char chars[] = "rwxrwxrwx";
for (size_t i = 0; i < 9; i++) {
// buf[i] = (mode & (1 << (8-i))) ? chars[i] : '-';
bool hasSetCurBit = mode & (1 << (8-i));
modeStrBuf[i] = hasSetCurBit ? chars[i] : '-';
}
modeStrBuf[9] = '\0';
}
called by Objective-C's .m:
#include “CrifanLib.h"
#interface JailbreakDetectionViewController ()
#end
#implementation JailbreakDetectionViewController
…
char* statToStr(struct stat* statInfo){
char stModeStr[10];
fileModeToStr(statInfo->st_mode, stModeStr);
...
}
...
done.