The calling convention is not a problem when calling C from python, because the python interpreter itself is written in C and thus uses the same calling convention as the C code.
This becomes a problem when combining code written in different compiled languages, such as C and Ada.
Typically, C is a system programming language and, therefore, a standard. This means that a compiler for any language will usually have special support for interacting with C. See here for an example of the interaction between C and Ada. If there is no special support, wrappers should be written at the assembly level.
If you need to call C ++ / Ada from python, you will need to perform a two-step process. The first step is to write a C wrapper around C ++ / Ada functions. The second step is to call the C shell from python.
Take, for example, the following C ++ class.
class Foo { public: Foo (); int bar (); ... };
If you want to make it available to python, you need to wrap it in C first:
extern "C" { typedef void *FooPtr; FooPtr foo_new () { return (FooPtr)new Foo(); } int foo_bar (FooPtr foo) { return ((Foo*)foo)->bar(); } ... }
Then you can call this from python. (Note: in real life there are tools to automate this, such as Boost.Python ).
Note that there are two aspects to writing a wrapper: conversion between conventions between calls and conversion between type representations. The later part, as a rule, is the most difficult, because as soon as you go beyond the framework of basic types, languages tend to have very different representations of equivalent types.