There are several.
C calls are often the lowest common denominator supported by most languages. The problem is that it does not really support the notion of objects. For objects to be supported you need some standardized way to describe object structure and lifetimes, and there have been several attempts at this:
- Compontent Obect Model (COM) is one of the older ones
- The Java Virtual Machine can easily interop between all JVM languages
- The .Net Common Language Infrastructure allows for easy interop between all CLI languages.
But many languages have intrinsic differences that are difficult to reconcile. Memory management is a big one, and some language features are just not practical without some form of garbage collection. Mutability is another potential problem, if the languages do not agree on what can change or not you will have issues. Not to mention all the possible issues with dynamic vs static type systems. So unless all languages participate in the same interoperability scheme you will have issues. And participating in such a scheme will mean inherent limitations that may not be very appealing to language designers.
A workaround is to use some Remote Procedure Call (RPC) protocol where data is serialized/deserialized instead. That would typically be easier to support by all languages, at the cost of some runtime overhead. See for example Open API or gRPC.