<style>
.reveal {
font-size: 32px;
}
</style>
# Talking C++ with Other Languages
### <small>someone get gcc on Duolingo</small>
<!-- Put the link to this slide here so people can follow -->
slides: https://hackmd.io/@sagnikb/HyyuYhA2o
code: [will add after talk]
---
## `static` and `extern`
---
## What does it take?
<ul>
<li>C++ programs turn into machine code at the end of the day<!-- .element: class="fragment" data-fragment-index="1" --></li>
<li>Simply <code>jump</code> to or <code>call</code> to other machine code?<!-- .element: class="fragment" data-fragment-index="2" --></li>
<li>How are arguments and return values passed?<!-- .element: class="fragment" data-fragment-index="3" --></li>
<li>How is memory managed?<!-- .element: class="fragment" data-fragment-index="4" --></li>
<li>And <em>where</em> to jump to?<!-- .element: class="fragment" data-fragment-index="5" --></li>
</ul>
----
---
## Calling C code from C++
```c
/* In Library.h */
const char* getHelloWorld(void);
```
```c
/* In Library.c */
const char* getHelloWorld() {
return "Hello world";
}
```
```cpp
/* In Main.cpp */
#include "Library.h"
int main() {
std::cout << getHelloWorld() << std::endl;
}
```
<span>
```shell
$ g++ -O3 Library.c Main.cpp -o Main
```
<!-- .element: class="fragment" data-fragment-index="1" --></span>
----
`extern "C"` Linkage
```c [2,4]
/* In Library.h */
extern "C" {
const char* getHelloWorld(void);
}
```
```c [1]
/* In Library.c */
const char* getHelloWorld() {
return "Hello world";
}
```
```cpp [1]
/* In Main.cpp */
#include "Library.h"
int main() {
std::cout << getHelloWorld() << std::endl;
}
```
```shell
$ g++ -O3 Library.c Main.cpp -o MainWithExtern
```
<span>What's the difference between `Main` and `MainWithExtern`? <!-- .element: class="fragment" data-fragment-index="1" --></span>
----
Excerpt of `int main()` in `objdump -M intel -D MainWithExtern`
```x86asm
...
call 401070 <_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l@plt>
call 401270 <getHelloWorld>
...
```
<span>Excerpt of<!-- .element: class="fragment" data-fragment-index="1" --></span><code>int main()</code><!-- .element: class="fragment" data-fragment-index="1" --> in<!-- .element: class="fragment" data-fragment-index="1" --> <code>objdump -M intel -D Main</code><!-- .element: class="fragment" data-fragment-index="1" -->
<span>
```x86asm
...
call 401070 <_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l@plt>
call 401270 <_Z13getHelloWorldv>
...
```
<!-- .element: class="fragment" data-fragment-index="1" --></span>
Note:
Mangling. Function overloading in C++ necessitates name mangling. No overloading in C, no mangling in C. C does not know how to interpret a mangled C++ name, so `extern "C"` linkage makes the names not mangled. It's a contract between the compiler and the linker: the compiler will not produce mangled names, and the linker will find the non-mangled names.
----
A more realistic example of building this:
```makefile
all: c cpp
c: Library.o
gcc -o MainC Library.o Main.c
cpp: Library.o
g++ -o MainCpp Library.o Main.cpp
Library.o: Library.c
gcc -c Library.c -o Library.o
```
----
In order to make header code compatible between C and C++, it is best practice to
```c
/* In Library.h */
#ifdef __cplusplus
extern "C" {
#endif
const char* getHelloWorld(void);
#ifdef __cplusplus
}
#endif
```
<span>When `#include`d in a C file, there's no `extern "C"`, but it is present when `#include`d in a C++ file.<!-- .element: class="fragment" data-fragment-index="1" --></span>
---
## Calling C++ Code from C
What could go wrong?
<ul>
<li>Overloaded functions<!-- .element: class="fragment" data-fragment-index="1" --></li>
<li>Class layout<!-- .element: class="fragment" data-fragment-index="2" --></li>
<li>Methods that take <code>this</code> as a parameter<!-- .element: class="fragment" data-fragment-index="3" --></li>
<li>Templates 😍<!-- .element: class="fragment" data-fragment-index="4" --></li>
<li>Exceptions, stack unwinding 😍<!-- .element: class="fragment" data-fragment-index="5" --></li>
</ul>
Note:
Boils down to de-sugaring these constructs into ones that fit within the C language.
----
### Overloaded Functions
```cpp
/* In Library.hpp */
int doWork();
int doWork(double aArg);
extern "C" {
int doWork_void() { return doWork(); };
int doWork_double(double aArg) { return doWork(aArg); };
}
```
Write glue code which can be `#include`d in a C file:
```c
/* In LibraryGlue.h */
int doWork_void(void);
int doWork_double(double aArg);
```
----
### C++ Classes
- Create opaque type exposed to C
- Generally a bad idea to access class members directly
- Be wary of conversions to base class pointers
----
----
### Templates
- Instantiate templates manually into `extern "C"` functions
- Call those functions from C code
{"metaMigratedAt":"2023-06-17T20:02:15.560Z","metaMigratedFrom":"YAML","title":"Talking C++ with Other Languages","breaks":true,"slideOptions":"{\"theme\":\"white\"}","contributors":"[{\"id\":\"bbc52c18-9822-4f81-8d84-cd68fe70b8e2\",\"add\":7535,\"del\":2362}]","description":"slides: https://hackmd.io/@sagnikb/HyyuYhA2o"}