1

There seems to be no documentation about interoperation with C sources originally written in C.

Or, is it better just create a library from vala code and call it from my C program?

How can I import other files in Vala?

seems to answer my question, I will check in few hours.

ruby_object
  • 1,229
  • 1
  • 12
  • 30
  • The link you provided is actually the correct solution. To achieve interoperability with C sources, you will need to write a VAPI file, see https://wiki.gnome.org/action/show//Projects/Vala/ManualBindings – Alexander Leithner Aug 31 '19 at 08:23
  • @AlexanderLeithner https://github.com/bigos/jacekFFI/blob/c5675045bab70e1e9ca0b23bb88c292c77433db1/gui.vala#L8 I ended up using delegation, It seems to work, but still I do not know if your suggestion is better – ruby_object Sep 02 '19 at 01:28
  • Actually, using `[CCode]` is what you would end up doing in a VAPI file, which just stores it in another file. So, your solution and the GNOME tutorial are functionally equal. – Alexander Leithner Sep 02 '19 at 13:26
  • But would moving the relevant code get rid of the compilation warnings on vala side? – ruby_object Sep 02 '19 at 15:16
  • What compiler warnings? Anyway, probably not because VAPI files are treated just like Vala code which just cannot contain any implementation. – Alexander Leithner Sep 02 '19 at 15:38

1 Answers1

5

This is a very simple example. Save the following C code as a file called a.c

#include <stdio.h>

void my_function() {
    printf("I am a function written in a C file\n");
}

Save the following Vala code as a file called b.vala

extern void my_function ();

void main() {
    my_function();
}

Then compile with:

valac a.c b.vala --output demo

There is a lot going on behind the scenes here. valac gets the job done, but a build system, like Meson, would be more appropriate for a project that will grow.

First valac recognises the Vala file in the list and compiles that to C. The extern void my_function (); tells the Vala compiler that my_function is defined externally and not in any of the Vala source files given. The Vala compiler just needs the function signature for type checking any calls from Vala and declaring the function in the generated C file. Instead of placing extern every where an interface file could be written. In Vala this ia a VAPI file. The VAPI keeps the translation information of the Vala symbols to the C symbols in one place and so helps project maintainability and readability.

Second valac passes the given C file and the generated C file to the C compiler. The C compiler compiles the files to object files then calls the linker to build a single binary. This might be clearer if you look at the generated C file. Use:

valac a.c b.vala --output demo --save-temps

The generated C file, b.c, looks like this:

/* b.c generated by valac 0.43.6.15-63bd-dirty, the Vala compiler
 * generated from b.vala, do not modify */

void my_function (void);
void _vala_main (void);

void
_vala_main (void)
{
        my_function ();
}

int
main (int argc,
      char ** argv)
{
        _vala_main ();
        return 0;
}

There is no #include C pre-processor directive used. Instead my_function is declared in the C file itself. Again an interface file could be written, a C header file this time instead of a VAPI file. You would then have to use [CCode(cheader_filename = "my_header.h")] in the VAPI so Vala then generates the #include.

AlThomas
  • 4,169
  • 12
  • 22
  • what is wrong with using delegate https://github.com/bigos/jacekFFI/blob/c5675045bab70e1e9ca0b23bb88c292c77433db1/gui.vala#L9 – ruby_object Sep 01 '19 at 23:58
  • A delegate in Vala is a function pointer in C. Function pointers are used to pass functions at runtime to another function. You didn't ask about passing functions to other functions. You asked how to call a function written in a C file from Vala and compile it. You should ask another question on Stack Overflow with more details – AlThomas Sep 02 '19 at 16:23
  • 1
    If I know know nothing, I do not know how to ask questions that make sense. Please accept my apologies. – ruby_object Sep 02 '19 at 18:05
  • 1
    That's no problem. Stack Overflow is a learning forum, so my answer is for other people as well. If you are getting compiler warnings may be you can start a new question and give the code sample and warnings. I guess the question would be something like: 'How do I pass a function defined in a C file to a Vala function as an argument?' – AlThomas Sep 02 '19 at 18:12
  • At this point https://github.com/bigos/jacekFFI I do not have C code. I'm afraid I have stumbled upon something tried by only few people.Clone my code and do make clean and then make run and you will see that Vala warns about methods not used and Idris warns about implicit declarations of functions. But ,the code seems to work. – ruby_object Sep 02 '19 at 21:14