SlideShare a Scribd company logo
Hourglass Interfaces 
for C++ APIs 
Stefanus Du Toit 
Thalmic Labs 
@stefanusdutoit 
Image © Erik Fitzpatrick, CC BY 2.0
Motivation and 
Introduction
Shared Libraries 
Library Code Data
Shared Libraries 
Interface 
Code Data 
Library
Shared Libraries 
Interface 
Code Data 
Client! 
Program 
Library 
Code Data
Shared Libraries 
Interface 
Code Data 
Client! 
Program 
Library 
Code Data 
ABI! 
! 
Common libraries
Different ABIs? Subtle problems… 
Class A 
Class B
Different ABIs? Subtle problems… 
Class A 
Class B 
Debug Build 
Release Build
My Goal for Libraries 
Get out of the client’s way.
My Goal for Libraries 
Don’t make my clients: 
• build my code if they don’t want to 
• change how they build their code 
• rebuild their code because I shipped a fix in mine 
• learn a new language if they don’t want to
Hourglass Interfaces for C++ APIs - CppCon 2014
Hourglass Interfaces for C++ APIs - CppCon 2014
Why does this help? 
• Avoids ABI-related binary compatibility issues 
• Enforces no use of non-trivial C++ types in the 
binary interface (e.g. std::string) 
• Keeps internal layout of data types a secret 
• Makes binding to other languages much easier 
! 
• Still get all the convenience of C++ at both ends
Example: libhairpoll 
• A library for creating hair-related polls, taking 
votes, and tallying the results
hairpoll.h 
typedef struct hairpoll* hairpoll_t; 
! 
hairpoll_t hairpoll_construct(const char* person); 
void hairpoll_destruct(hairpoll_t poll); 
! 
int32_t hairpoll_add_option(hairpoll_t hairpoll, 
const char* name, const char* image_url); 
! 
void hairpoll_vote(hairpoll_t hairpoll, int32_t option); 
! 
typedef void (*hairpoll_result_handler_t)(void* client_data, 
const char* name, int32_t votes, const char* html); 
! 
void hairpoll_tally(const hairpoll_t hairpoll, 
hairpoll_result_handler_t handler, void* client_data);
HairPoll class - client-facing 
class HairPoll { 
public: 
HairPoll(std::string person); 
~HairPoll(); 
! 
int addOption(std::string name, std::string imageUrl); 
void vote(int option); 
! 
struct Result { 
std::string name; 
int votes; 
std::string html; 
}; 
std::vector<Result> results() const; 
! 
private: 
hairpoll_t _opaque; 
};
Best Practices
Parts of C to use in the thin API 
• C89 + const and // comments 
• Functions, but no variadic functions 
• C primitive types (char, void, etc.) 
• Pointers 
• forward-declared structs 
• enumerations 
• Function pointers are OK, too
Opaque Types 
typedef struct hairpoll* hairpoll_t; 
! 
void hairpoll_vote( 
hairpoll_t hairpoll, 
int32_t option 
);
Opaque Types 
extern "C" 
struct hairpoll { 
Poll actual; 
};
Opaque Types 
extern "C" 
struct hairpoll { 
template<typename... Args> 
hairpoll(Args&&... args) 
: actual(std::forward<Args>(args)...) 
{ 
} 
! 
Poll actual; 
};
Opaque Types 
class Poll { 
public: 
Poll(std::string person); 
! 
struct option { 
option(std::string name, std::string url); 
! 
std::string name; 
std::string url; 
int votes; 
}; 
! 
std::string person; 
std::vector<option> options; 
};
Opaque Types 
hairpoll_t 
hairpoll_construct(const char* person) 
{ 
return new hairpoll(person); 
} 
! 
void hairpoll_destruct(hairpoll_t poll) 
{ 
delete poll; 
}
Integral types 
Prefer stdint.h types (int32_t, int64_t, etc.) over plain 
C integer types (short, int, long): 
! 
void hairpoll_vote( 
hairpoll_t hairpoll, 
int32_t option 
);
Integral types 
Using char is OK, though: 
! 
int32_t 
hairpoll_add_option( 
hairpoll_t hairpoll, 
const char* name, 
const char* image_url 
);
Enumerations 
typedef enum motu_alignment { 
heroic_warrior = 0, 
evil_warrior = 1, 
}; 
! 
int32_t motu_count( 
int32_t alignment 
);
Error Handling 
void hairpoll_vote( 
hairpoll_t hairpoll, 
int32_t option, 
error_t* out_error 
);
Error Handling 
typedef struct error* error_t; 
! 
const char* error_message( 
error_t error 
); 
! 
void error_destruct(error_t error); 
! 
! 
void hairpoll_vote(hairpoll_t hairpoll, int32_t option, error_t* out_error);
Errors → Exceptions 
struct Error { 
Error() : opaque(nullptr) {} 
~Error() { if (opaque) { error_destruct(opaque); } } 
error_t opaque; 
}; 
! 
class ThrowOnError { 
public: 
~ThrowOnError() noexcept(false) { 
if (_error.opaque) { 
throw std::runtime_error(error_message(_error.opaque)); 
} 
} 
! 
operator error_t*() { return &_error.opaque; } 
! 
private: 
Error _error; 
};
Errors → Exceptions 
void hairpoll_vote(hairpoll_t hairpoll, int32_t option, error_t* out_error); 
! 
void vote(int option) { 
return hairpoll_vote( 
_opaque, 
option, 
ThrowOnError{} 
); 
}
Exceptions → Errors 
template<typename Fn> 
bool translateExceptions(error_t* out_error, Fn&& fn) 
{ 
try { 
fn(); 
} catch (const std::exception& e) { 
*out_error = new error{e.what()}; 
return false; 
} catch (...) { 
*out_error = new error{"Unknown internal error"}; 
return false; 
} 
return true; 
}
Exceptions → Errors 
void hairpoll_vote(const hairpoll_t poll, 
int32_t option, error_t* out_error) 
{ 
translateExceptions(out_error, [&]{ 
if (option < 0 || 
option >= poll->actual.options.size()) { 
throw std::runtime_error("Bad optn index"); 
} 
! 
poll->actual.options[option].votes++; 
}); 
}
Callbacks 
typedef void (*hairpoll_result_handler_t)( 
void* client_data, 
const char* name, 
int32_t votes, 
const char* html 
); 
! 
void hairpoll_tally(const hairpoll_t hairpoll, 
hairpoll_result_handler_t handler, 
void* client_data, error_t* out_error);
Using lambdas as callbacks 
std::vector<Result> results() const { 
std::vector<Result> ret; 
! 
auto addResult = [&ret](const char* name, int32_t votes, 
const char* html){ 
ret.push_back(Result{name, votes, html}); 
}; 
! 
auto callback = [](void* client_data, const char* name, int32_t votes, 
const char* html){ 
auto fn = static_cast<decltype(&addResult)>(client_data); 
(*fn)(name, votes, html); 
}; 
! 
hairpoll_tally(_opaque, callback, &addResult, ThrowOnError{}); 
! 
return ret; 
}
Symbol visibility 
#if defined(_WIN32) || defined(__CYGWIN__) 
#ifdef hairpoll_EXPORTS 
#ifdef __GNUC__ 
#define HAIRPOLL_EXPORT __attribute__ ((dllexport)) 
#else 
#define HAIRPOLL_EXPORT __declspec(dllexport) 
#endif 
#else 
#ifdef __GNUC__ 
#define HAIRPOLL_EXPORT __attribute__ ((dllimport)) 
#else 
#define HAIRPOLL_EXPORT __declspec(dllimport) 
#endif 
#endif 
#else 
#if __GNUC__ >= 4 
#define HAIRPOLL_EXPORT __attribute__ ((visibility ("default"))) 
#else 
#define HAIRPOLL_EXPORT 
#endif 
#endif
Symbol visibility 
#include "visibility.h" 
! 
… 
! 
HAIRPOLL_EXPORT 
hairpoll_t hairpoll_construct(const char* person); 
! 
HAIRPOLL_EXPORT 
void hairpoll_destruct(hairpoll_t poll); 
! 
…
Symbol visibility 
On Clang and GCC, add to your compile: 
! 
-fvisibility=hidden 
! 
(applies to library only)
Remember to extern “C”! 
#ifdef __cplusplus 
extern "C" { 
#endif 
! 
// C API goes here 
! 
#ifdef __cplusplus 
} // extern "C" 
#endif
Lifetime and Ownership 
• Keep it simple: construct (if needed) and destruct 
• Always use RAII on the client side! 
• Can use refcounting (e.g. shared_ptr) both 
internally to the library and in the client 
• For callbacks, you can use the stack
Interfacing with those 
“other” languages
Foreign Function Interfaces 
• “something that allows calling code written in one 
language from another language” 
• C = de-facto standard 
• Languages with support for calling C functions in 
shared libraries include: 
• Common Lisp, Java, JavaScript, Matlab, .NET 
(C#, F#, etc.), Python, Ruby, OCaml, basically everything…
Hair Polls in Python 
hairpoll = lib.hairpoll_construct("Stefanus Du Toit", None) 
! 
skeletor = lib.hairpoll_add_option(hairpoll, "Skeletor", 
"<long URL omitted>", None) 
beast = lib.hairpoll_add_option(hairpoll, "Beast Man", 
"<long URL omitted>", None) 
! 
lib.hairpoll_vote(hairpoll, skeletor, None) 
lib.hairpoll_vote(hairpoll, beast, None) 
lib.hairpoll_vote(hairpoll, beast, None) 
! 
def print_result(client_data, name, votes, html): 
print name, votes 
! 
lib.hairpoll_tally(hairpoll, hairpoll_result_handler(print_result), 
None, None) 
! 
lib.hairpoll_destruct(hairpoll)
Hair Polls In Python 
from ctypes import * 
! 
lib = CDLL("libhairpoll.dylib") 
lib.hairpoll_construct.restype = c_void_p 
lib.hairpoll_construct.argtypes = [c_char_p, c_void_p] 
! 
lib.hairpoll_destruct.restype = None 
lib.hairpoll_destruct.argtypes = [c_void_p] 
! 
lib.hairpoll_add_option.restype = c_int 
lib.hairpoll_add_option.argtypes = [c_void_p, c_char_p, c_char_p, c_void_p] 
! 
lib.hairpoll_vote.restype = None 
lib.hairpoll_vote.argtypes = [c_void_p, c_int, c_void_p] 
! 
hairpoll_result_handler = CFUNCTYPE(None, c_void_p, c_char_p, c_int, c_char_p) 
lib.hairpoll_tally.restype = None 
lib.hairpoll_tally.argtypes = [c_void_p, hairpoll_result_handler, c_void_p, 
c_void_p]
Summary 
• Hourglass = C++ on top of C89 on top of C++ 
• Avoids ABI issues, sneaky dependencies, etc. 
• Hides object layout and other implementation 
details 
• Makes FFI bindings easy
Hourglass Interfaces for C++ APIs - CppCon 2014
Q&A 
http://blog.sduto.it/ @stefanusdutoit

More Related Content

What's hot

Regular expression (compiler)
Regular expression (compiler)Regular expression (compiler)
Regular expression (compiler)
Jagjit Wilku
 
Structure in c
Structure in cStructure in c
JavaScript - Chapter 13 - Browser Object Model(BOM)
JavaScript - Chapter 13 - Browser Object Model(BOM)JavaScript - Chapter 13 - Browser Object Model(BOM)
JavaScript - Chapter 13 - Browser Object Model(BOM)
WebStackAcademy
 
Javascript operators
Javascript operatorsJavascript operators
Javascript operators
Mohit Rana
 
Storage classes in C
Storage classes in C Storage classes in C
Storage classes in C
Self employed
 
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1
Dave Cross
 
Heuristics Search Techniques in AI
Heuristics Search Techniques in AI Heuristics Search Techniques in AI
Heuristics Search Techniques in AI
Bharat Bhushan
 
Dijkstra s algorithm
Dijkstra s algorithmDijkstra s algorithm
Dijkstra s algorithm
mansab MIRZA
 
1 introdcution to ds 2-2019 abstract stack and queue
1   introdcution to ds 2-2019  abstract stack and queue1   introdcution to ds 2-2019  abstract stack and queue
1 introdcution to ds 2-2019 abstract stack and queue
ِِِAhmed R. A. Shamsan
 
Dijkstra's algorithm presentation
Dijkstra's algorithm presentationDijkstra's algorithm presentation
Dijkstra's algorithm presentation
Subid Biswas
 
Exception handling
Exception handlingException handling
Exception handling
Iblesoft
 
Manipulators
ManipulatorsManipulators
Manipulators
VaishnaviVaishnavi17
 
Formatted Console I/O Operations in C++
Formatted Console I/O Operations in C++Formatted Console I/O Operations in C++
Formatted Console I/O Operations in C++
sujathavvv
 
C++ oop
C++ oopC++ oop
C++ oop
Sunil OS
 
Structure in C
Structure in CStructure in C
Structure in C
Kamal Acharya
 
Finite state Transducers and mealy Machine
Finite state Transducers and mealy Machine Finite state Transducers and mealy Machine
Finite state Transducers and mealy Machine
Nadeem Qasmi
 
CFG to CNF
CFG to CNFCFG to CNF
CFG to CNF
Zain Ul Abiden
 
Recursion in c++
Recursion in c++Recursion in c++
Recursion in c++
Abdul Rehman
 
Rope
RopeRope
20.4 Java interfaces and abstraction
20.4 Java interfaces and abstraction20.4 Java interfaces and abstraction
20.4 Java interfaces and abstraction
Intro C# Book
 

What's hot (20)

Regular expression (compiler)
Regular expression (compiler)Regular expression (compiler)
Regular expression (compiler)
 
Structure in c
Structure in cStructure in c
Structure in c
 
JavaScript - Chapter 13 - Browser Object Model(BOM)
JavaScript - Chapter 13 - Browser Object Model(BOM)JavaScript - Chapter 13 - Browser Object Model(BOM)
JavaScript - Chapter 13 - Browser Object Model(BOM)
 
Javascript operators
Javascript operatorsJavascript operators
Javascript operators
 
Storage classes in C
Storage classes in C Storage classes in C
Storage classes in C
 
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1
 
Heuristics Search Techniques in AI
Heuristics Search Techniques in AI Heuristics Search Techniques in AI
Heuristics Search Techniques in AI
 
Dijkstra s algorithm
Dijkstra s algorithmDijkstra s algorithm
Dijkstra s algorithm
 
1 introdcution to ds 2-2019 abstract stack and queue
1   introdcution to ds 2-2019  abstract stack and queue1   introdcution to ds 2-2019  abstract stack and queue
1 introdcution to ds 2-2019 abstract stack and queue
 
Dijkstra's algorithm presentation
Dijkstra's algorithm presentationDijkstra's algorithm presentation
Dijkstra's algorithm presentation
 
Exception handling
Exception handlingException handling
Exception handling
 
Manipulators
ManipulatorsManipulators
Manipulators
 
Formatted Console I/O Operations in C++
Formatted Console I/O Operations in C++Formatted Console I/O Operations in C++
Formatted Console I/O Operations in C++
 
C++ oop
C++ oopC++ oop
C++ oop
 
Structure in C
Structure in CStructure in C
Structure in C
 
Finite state Transducers and mealy Machine
Finite state Transducers and mealy Machine Finite state Transducers and mealy Machine
Finite state Transducers and mealy Machine
 
CFG to CNF
CFG to CNFCFG to CNF
CFG to CNF
 
Recursion in c++
Recursion in c++Recursion in c++
Recursion in c++
 
Rope
RopeRope
Rope
 
20.4 Java interfaces and abstraction
20.4 Java interfaces and abstraction20.4 Java interfaces and abstraction
20.4 Java interfaces and abstraction
 

Viewers also liked

Connecting C++ and JavaScript on the Web with Embind
Connecting C++ and JavaScript on the Web with EmbindConnecting C++ and JavaScript on the Web with Embind
Connecting C++ and JavaScript on the Web with Embind
Chad Austin
 
Refactoring
RefactoringRefactoring
Refactoring
Herez Moise Kattan
 
Software Development Practices Patterns
Software Development Practices PatternsSoftware Development Practices Patterns
Software Development Practices Patterns
Herez Moise Kattan
 
Introduction to Mob Programming
Introduction to Mob ProgrammingIntroduction to Mob Programming
Introduction to Mob Programming
Herez Moise Kattan
 
Programação simultânea em pares
Programação simultânea em paresProgramação simultânea em pares
Programação simultânea em pares
Herez Moise Kattan
 
Nonvital pulp therapy in pediatric dentistry
Nonvital pulp therapy in pediatric dentistryNonvital pulp therapy in pediatric dentistry
Nonvital pulp therapy in pediatric dentistry
Priyank Pareek
 
Cleaning and shaping the root canal system
Cleaning and shaping the root canal systemCleaning and shaping the root canal system
Cleaning and shaping the root canal system
Parth Thakkar
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
Scott Wlaschin
 
How To Design A Good A P I And Why It Matters G O O G L E
How To Design A Good  A P I And Why It Matters    G O O G L EHow To Design A Good  A P I And Why It Matters    G O O G L E
How To Design A Good A P I And Why It Matters G O O G L E
guestbe92f4
 

Viewers also liked (9)

Connecting C++ and JavaScript on the Web with Embind
Connecting C++ and JavaScript on the Web with EmbindConnecting C++ and JavaScript on the Web with Embind
Connecting C++ and JavaScript on the Web with Embind
 
Refactoring
RefactoringRefactoring
Refactoring
 
Software Development Practices Patterns
Software Development Practices PatternsSoftware Development Practices Patterns
Software Development Practices Patterns
 
Introduction to Mob Programming
Introduction to Mob ProgrammingIntroduction to Mob Programming
Introduction to Mob Programming
 
Programação simultânea em pares
Programação simultânea em paresProgramação simultânea em pares
Programação simultânea em pares
 
Nonvital pulp therapy in pediatric dentistry
Nonvital pulp therapy in pediatric dentistryNonvital pulp therapy in pediatric dentistry
Nonvital pulp therapy in pediatric dentistry
 
Cleaning and shaping the root canal system
Cleaning and shaping the root canal systemCleaning and shaping the root canal system
Cleaning and shaping the root canal system
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
 
How To Design A Good A P I And Why It Matters G O O G L E
How To Design A Good  A P I And Why It Matters    G O O G L EHow To Design A Good  A P I And Why It Matters    G O O G L E
How To Design A Good A P I And Why It Matters G O O G L E
 

Similar to Hourglass Interfaces for C++ APIs - CppCon 2014

Modern C++
Modern C++Modern C++
Modern C++
Michael Clark
 
Gcrc talk
Gcrc talkGcrc talk
Gcrc talk
Tejas Dinkar
 
Bringing nullability into existing code - dammit is not the answer.pptx
Bringing nullability into existing code - dammit is not the answer.pptxBringing nullability into existing code - dammit is not the answer.pptx
Bringing nullability into existing code - dammit is not the answer.pptx
Maarten Balliauw
 
Glimpses of C++0x
Glimpses of C++0xGlimpses of C++0x
Glimpses of C++0x
ppd1961
 
devLink - What's New in C# 4?
devLink - What's New in C# 4?devLink - What's New in C# 4?
devLink - What's New in C# 4?
Kevin Pilch
 
Solid C++ by Example
Solid C++ by ExampleSolid C++ by Example
Solid C++ by Example
Olve Maudal
 
Session 2 - Objective-C basics
Session 2 - Objective-C basicsSession 2 - Objective-C basics
Session 2 - Objective-C basics
Vu Tran Lam
 
Things to Remember When Developing 64-bit Software
Things to Remember When Developing 64-bit SoftwareThings to Remember When Developing 64-bit Software
Things to Remember When Developing 64-bit Software
Andrey Karpov
 
What has to be paid attention when reviewing code of the library you develop
What has to be paid attention when reviewing code of the library you developWhat has to be paid attention when reviewing code of the library you develop
What has to be paid attention when reviewing code of the library you develop
Andrey Karpov
 
Fundamentals of Programming Constructs.pptx
Fundamentals of  Programming Constructs.pptxFundamentals of  Programming Constructs.pptx
Fundamentals of Programming Constructs.pptx
vijayapraba1
 
Design Patterns in Modern C++
Design Patterns in Modern C++Design Patterns in Modern C++
Design Patterns in Modern C++
Dmitri Nesteruk
 
Vocabulary Types in C++17
Vocabulary Types in C++17Vocabulary Types in C++17
Vocabulary Types in C++17
Bartlomiej Filipek
 
Aspdot
AspdotAspdot
Programming using c++ tool
Programming using c++ toolProgramming using c++ tool
Programming using c++ tool
Abdullah Jan
 
Lecture03
Lecture03Lecture03
Lecture03
elearning_portal
 
Hooking signals and dumping the callstack
Hooking signals and dumping the callstackHooking signals and dumping the callstack
Hooking signals and dumping the callstack
Thierry Gayet
 
C
CC
Presentation 2nd
Presentation 2ndPresentation 2nd
Presentation 2nd
Connex
 
Data types and Operators
Data types and OperatorsData types and Operators
Data types and Operators
raksharao
 
Introduction Of C++
Introduction Of C++Introduction Of C++
Introduction Of C++
Sangharsh agarwal
 

Similar to Hourglass Interfaces for C++ APIs - CppCon 2014 (20)

Modern C++
Modern C++Modern C++
Modern C++
 
Gcrc talk
Gcrc talkGcrc talk
Gcrc talk
 
Bringing nullability into existing code - dammit is not the answer.pptx
Bringing nullability into existing code - dammit is not the answer.pptxBringing nullability into existing code - dammit is not the answer.pptx
Bringing nullability into existing code - dammit is not the answer.pptx
 
Glimpses of C++0x
Glimpses of C++0xGlimpses of C++0x
Glimpses of C++0x
 
devLink - What's New in C# 4?
devLink - What's New in C# 4?devLink - What's New in C# 4?
devLink - What's New in C# 4?
 
Solid C++ by Example
Solid C++ by ExampleSolid C++ by Example
Solid C++ by Example
 
Session 2 - Objective-C basics
Session 2 - Objective-C basicsSession 2 - Objective-C basics
Session 2 - Objective-C basics
 
Things to Remember When Developing 64-bit Software
Things to Remember When Developing 64-bit SoftwareThings to Remember When Developing 64-bit Software
Things to Remember When Developing 64-bit Software
 
What has to be paid attention when reviewing code of the library you develop
What has to be paid attention when reviewing code of the library you developWhat has to be paid attention when reviewing code of the library you develop
What has to be paid attention when reviewing code of the library you develop
 
Fundamentals of Programming Constructs.pptx
Fundamentals of  Programming Constructs.pptxFundamentals of  Programming Constructs.pptx
Fundamentals of Programming Constructs.pptx
 
Design Patterns in Modern C++
Design Patterns in Modern C++Design Patterns in Modern C++
Design Patterns in Modern C++
 
Vocabulary Types in C++17
Vocabulary Types in C++17Vocabulary Types in C++17
Vocabulary Types in C++17
 
Aspdot
AspdotAspdot
Aspdot
 
Programming using c++ tool
Programming using c++ toolProgramming using c++ tool
Programming using c++ tool
 
Lecture03
Lecture03Lecture03
Lecture03
 
Hooking signals and dumping the callstack
Hooking signals and dumping the callstackHooking signals and dumping the callstack
Hooking signals and dumping the callstack
 
C
CC
C
 
Presentation 2nd
Presentation 2ndPresentation 2nd
Presentation 2nd
 
Data types and Operators
Data types and OperatorsData types and Operators
Data types and Operators
 
Introduction Of C++
Introduction Of C++Introduction Of C++
Introduction Of C++
 

Recently uploaded

05. Ruby Control Structures - Ruby Core Teaching
05. Ruby Control Structures - Ruby Core Teaching05. Ruby Control Structures - Ruby Core Teaching
05. Ruby Control Structures - Ruby Core Teaching
quanhoangd129
 
TEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with YouTEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with You
marcofolio
 
Hotel Management Software Development Company
Hotel Management Software Development CompanyHotel Management Software Development Company
Hotel Management Software Development Company
XongoLab Technologies LLP
 
How to Secure Your Kubernetes Software Supply Chain at Scale
How to Secure Your Kubernetes Software Supply Chain at ScaleHow to Secure Your Kubernetes Software Supply Chain at Scale
How to Secure Your Kubernetes Software Supply Chain at Scale
Anchore
 
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
87tomato
 
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
jealousviolet
 
PathSpotter: Exploring Tested Paths to Discover Missing Tests (FSE 2024)
PathSpotter: Exploring Tested Paths to Discover Missing Tests (FSE 2024)PathSpotter: Exploring Tested Paths to Discover Missing Tests (FSE 2024)
PathSpotter: Exploring Tested Paths to Discover Missing Tests (FSE 2024)
andrehoraa
 
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
dream girl
 
Fantastic Design Patterns and Where to use them No Notes.pdf
Fantastic Design Patterns and Where to use them No Notes.pdfFantastic Design Patterns and Where to use them No Notes.pdf
Fantastic Design Patterns and Where to use them No Notes.pdf
6m9p7qnjj8
 
Applitools Autonomous 2.0 Sneak Peek.pdf
Applitools Autonomous 2.0 Sneak Peek.pdfApplitools Autonomous 2.0 Sneak Peek.pdf
Applitools Autonomous 2.0 Sneak Peek.pdf
Applitools
 
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in CityGirls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
neshakor5152
 
Predicting Test Results without Execution (FSE 2024)
Predicting Test Results without Execution (FSE 2024)Predicting Test Results without Execution (FSE 2024)
Predicting Test Results without Execution (FSE 2024)
andrehoraa
 
06. Ruby Array & Hash - Ruby Core Teaching
06. Ruby Array & Hash - Ruby Core Teaching06. Ruby Array & Hash - Ruby Core Teaching
06. Ruby Array & Hash - Ruby Core Teaching
quanhoangd129
 
UMiami degree offer diploma Transcript
UMiami degree offer diploma TranscriptUMiami degree offer diploma Transcript
UMiami degree offer diploma Transcript
attueb
 
02. Ruby Basic slides - Ruby Core Teaching
02. Ruby Basic slides - Ruby Core Teaching02. Ruby Basic slides - Ruby Core Teaching
02. Ruby Basic slides - Ruby Core Teaching
quanhoangd129
 
Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...
Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...
Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...
revolutionary575
 
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdfA Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
kalichargn70th171
 
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdfAI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
Daniel Zivkovic
 
ERP Software Solutions Provider in Coimbatore
ERP Software Solutions Provider in CoimbatoreERP Software Solutions Provider in Coimbatore
ERP Software Solutions Provider in Coimbatore
Nextskill Technologies
 
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
45unexpected
 

Recently uploaded (20)

05. Ruby Control Structures - Ruby Core Teaching
05. Ruby Control Structures - Ruby Core Teaching05. Ruby Control Structures - Ruby Core Teaching
05. Ruby Control Structures - Ruby Core Teaching
 
TEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with YouTEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with You
 
Hotel Management Software Development Company
Hotel Management Software Development CompanyHotel Management Software Development Company
Hotel Management Software Development Company
 
How to Secure Your Kubernetes Software Supply Chain at Scale
How to Secure Your Kubernetes Software Supply Chain at ScaleHow to Secure Your Kubernetes Software Supply Chain at Scale
How to Secure Your Kubernetes Software Supply Chain at Scale
 
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
 
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
 
PathSpotter: Exploring Tested Paths to Discover Missing Tests (FSE 2024)
PathSpotter: Exploring Tested Paths to Discover Missing Tests (FSE 2024)PathSpotter: Exploring Tested Paths to Discover Missing Tests (FSE 2024)
PathSpotter: Exploring Tested Paths to Discover Missing Tests (FSE 2024)
 
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
 
Fantastic Design Patterns and Where to use them No Notes.pdf
Fantastic Design Patterns and Where to use them No Notes.pdfFantastic Design Patterns and Where to use them No Notes.pdf
Fantastic Design Patterns and Where to use them No Notes.pdf
 
Applitools Autonomous 2.0 Sneak Peek.pdf
Applitools Autonomous 2.0 Sneak Peek.pdfApplitools Autonomous 2.0 Sneak Peek.pdf
Applitools Autonomous 2.0 Sneak Peek.pdf
 
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in CityGirls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
 
Predicting Test Results without Execution (FSE 2024)
Predicting Test Results without Execution (FSE 2024)Predicting Test Results without Execution (FSE 2024)
Predicting Test Results without Execution (FSE 2024)
 
06. Ruby Array & Hash - Ruby Core Teaching
06. Ruby Array & Hash - Ruby Core Teaching06. Ruby Array & Hash - Ruby Core Teaching
06. Ruby Array & Hash - Ruby Core Teaching
 
UMiami degree offer diploma Transcript
UMiami degree offer diploma TranscriptUMiami degree offer diploma Transcript
UMiami degree offer diploma Transcript
 
02. Ruby Basic slides - Ruby Core Teaching
02. Ruby Basic slides - Ruby Core Teaching02. Ruby Basic slides - Ruby Core Teaching
02. Ruby Basic slides - Ruby Core Teaching
 
Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...
Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...
Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...
 
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdfA Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
 
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdfAI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
 
ERP Software Solutions Provider in Coimbatore
ERP Software Solutions Provider in CoimbatoreERP Software Solutions Provider in Coimbatore
ERP Software Solutions Provider in Coimbatore
 
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
 

Hourglass Interfaces for C++ APIs - CppCon 2014

  • 1. Hourglass Interfaces for C++ APIs Stefanus Du Toit Thalmic Labs @stefanusdutoit Image © Erik Fitzpatrick, CC BY 2.0
  • 4. Shared Libraries Interface Code Data Library
  • 5. Shared Libraries Interface Code Data Client! Program Library Code Data
  • 6. Shared Libraries Interface Code Data Client! Program Library Code Data ABI! ! Common libraries
  • 7. Different ABIs? Subtle problems… Class A Class B
  • 8. Different ABIs? Subtle problems… Class A Class B Debug Build Release Build
  • 9. My Goal for Libraries Get out of the client’s way.
  • 10. My Goal for Libraries Don’t make my clients: • build my code if they don’t want to • change how they build their code • rebuild their code because I shipped a fix in mine • learn a new language if they don’t want to
  • 13. Why does this help? • Avoids ABI-related binary compatibility issues • Enforces no use of non-trivial C++ types in the binary interface (e.g. std::string) • Keeps internal layout of data types a secret • Makes binding to other languages much easier ! • Still get all the convenience of C++ at both ends
  • 14. Example: libhairpoll • A library for creating hair-related polls, taking votes, and tallying the results
  • 15. hairpoll.h typedef struct hairpoll* hairpoll_t; ! hairpoll_t hairpoll_construct(const char* person); void hairpoll_destruct(hairpoll_t poll); ! int32_t hairpoll_add_option(hairpoll_t hairpoll, const char* name, const char* image_url); ! void hairpoll_vote(hairpoll_t hairpoll, int32_t option); ! typedef void (*hairpoll_result_handler_t)(void* client_data, const char* name, int32_t votes, const char* html); ! void hairpoll_tally(const hairpoll_t hairpoll, hairpoll_result_handler_t handler, void* client_data);
  • 16. HairPoll class - client-facing class HairPoll { public: HairPoll(std::string person); ~HairPoll(); ! int addOption(std::string name, std::string imageUrl); void vote(int option); ! struct Result { std::string name; int votes; std::string html; }; std::vector<Result> results() const; ! private: hairpoll_t _opaque; };
  • 18. Parts of C to use in the thin API • C89 + const and // comments • Functions, but no variadic functions • C primitive types (char, void, etc.) • Pointers • forward-declared structs • enumerations • Function pointers are OK, too
  • 19. Opaque Types typedef struct hairpoll* hairpoll_t; ! void hairpoll_vote( hairpoll_t hairpoll, int32_t option );
  • 20. Opaque Types extern "C" struct hairpoll { Poll actual; };
  • 21. Opaque Types extern "C" struct hairpoll { template<typename... Args> hairpoll(Args&&... args) : actual(std::forward<Args>(args)...) { } ! Poll actual; };
  • 22. Opaque Types class Poll { public: Poll(std::string person); ! struct option { option(std::string name, std::string url); ! std::string name; std::string url; int votes; }; ! std::string person; std::vector<option> options; };
  • 23. Opaque Types hairpoll_t hairpoll_construct(const char* person) { return new hairpoll(person); } ! void hairpoll_destruct(hairpoll_t poll) { delete poll; }
  • 24. Integral types Prefer stdint.h types (int32_t, int64_t, etc.) over plain C integer types (short, int, long): ! void hairpoll_vote( hairpoll_t hairpoll, int32_t option );
  • 25. Integral types Using char is OK, though: ! int32_t hairpoll_add_option( hairpoll_t hairpoll, const char* name, const char* image_url );
  • 26. Enumerations typedef enum motu_alignment { heroic_warrior = 0, evil_warrior = 1, }; ! int32_t motu_count( int32_t alignment );
  • 27. Error Handling void hairpoll_vote( hairpoll_t hairpoll, int32_t option, error_t* out_error );
  • 28. Error Handling typedef struct error* error_t; ! const char* error_message( error_t error ); ! void error_destruct(error_t error); ! ! void hairpoll_vote(hairpoll_t hairpoll, int32_t option, error_t* out_error);
  • 29. Errors → Exceptions struct Error { Error() : opaque(nullptr) {} ~Error() { if (opaque) { error_destruct(opaque); } } error_t opaque; }; ! class ThrowOnError { public: ~ThrowOnError() noexcept(false) { if (_error.opaque) { throw std::runtime_error(error_message(_error.opaque)); } } ! operator error_t*() { return &_error.opaque; } ! private: Error _error; };
  • 30. Errors → Exceptions void hairpoll_vote(hairpoll_t hairpoll, int32_t option, error_t* out_error); ! void vote(int option) { return hairpoll_vote( _opaque, option, ThrowOnError{} ); }
  • 31. Exceptions → Errors template<typename Fn> bool translateExceptions(error_t* out_error, Fn&& fn) { try { fn(); } catch (const std::exception& e) { *out_error = new error{e.what()}; return false; } catch (...) { *out_error = new error{"Unknown internal error"}; return false; } return true; }
  • 32. Exceptions → Errors void hairpoll_vote(const hairpoll_t poll, int32_t option, error_t* out_error) { translateExceptions(out_error, [&]{ if (option < 0 || option >= poll->actual.options.size()) { throw std::runtime_error("Bad optn index"); } ! poll->actual.options[option].votes++; }); }
  • 33. Callbacks typedef void (*hairpoll_result_handler_t)( void* client_data, const char* name, int32_t votes, const char* html ); ! void hairpoll_tally(const hairpoll_t hairpoll, hairpoll_result_handler_t handler, void* client_data, error_t* out_error);
  • 34. Using lambdas as callbacks std::vector<Result> results() const { std::vector<Result> ret; ! auto addResult = [&ret](const char* name, int32_t votes, const char* html){ ret.push_back(Result{name, votes, html}); }; ! auto callback = [](void* client_data, const char* name, int32_t votes, const char* html){ auto fn = static_cast<decltype(&addResult)>(client_data); (*fn)(name, votes, html); }; ! hairpoll_tally(_opaque, callback, &addResult, ThrowOnError{}); ! return ret; }
  • 35. Symbol visibility #if defined(_WIN32) || defined(__CYGWIN__) #ifdef hairpoll_EXPORTS #ifdef __GNUC__ #define HAIRPOLL_EXPORT __attribute__ ((dllexport)) #else #define HAIRPOLL_EXPORT __declspec(dllexport) #endif #else #ifdef __GNUC__ #define HAIRPOLL_EXPORT __attribute__ ((dllimport)) #else #define HAIRPOLL_EXPORT __declspec(dllimport) #endif #endif #else #if __GNUC__ >= 4 #define HAIRPOLL_EXPORT __attribute__ ((visibility ("default"))) #else #define HAIRPOLL_EXPORT #endif #endif
  • 36. Symbol visibility #include "visibility.h" ! … ! HAIRPOLL_EXPORT hairpoll_t hairpoll_construct(const char* person); ! HAIRPOLL_EXPORT void hairpoll_destruct(hairpoll_t poll); ! …
  • 37. Symbol visibility On Clang and GCC, add to your compile: ! -fvisibility=hidden ! (applies to library only)
  • 38. Remember to extern “C”! #ifdef __cplusplus extern "C" { #endif ! // C API goes here ! #ifdef __cplusplus } // extern "C" #endif
  • 39. Lifetime and Ownership • Keep it simple: construct (if needed) and destruct • Always use RAII on the client side! • Can use refcounting (e.g. shared_ptr) both internally to the library and in the client • For callbacks, you can use the stack
  • 40. Interfacing with those “other” languages
  • 41. Foreign Function Interfaces • “something that allows calling code written in one language from another language” • C = de-facto standard • Languages with support for calling C functions in shared libraries include: • Common Lisp, Java, JavaScript, Matlab, .NET (C#, F#, etc.), Python, Ruby, OCaml, basically everything…
  • 42. Hair Polls in Python hairpoll = lib.hairpoll_construct("Stefanus Du Toit", None) ! skeletor = lib.hairpoll_add_option(hairpoll, "Skeletor", "<long URL omitted>", None) beast = lib.hairpoll_add_option(hairpoll, "Beast Man", "<long URL omitted>", None) ! lib.hairpoll_vote(hairpoll, skeletor, None) lib.hairpoll_vote(hairpoll, beast, None) lib.hairpoll_vote(hairpoll, beast, None) ! def print_result(client_data, name, votes, html): print name, votes ! lib.hairpoll_tally(hairpoll, hairpoll_result_handler(print_result), None, None) ! lib.hairpoll_destruct(hairpoll)
  • 43. Hair Polls In Python from ctypes import * ! lib = CDLL("libhairpoll.dylib") lib.hairpoll_construct.restype = c_void_p lib.hairpoll_construct.argtypes = [c_char_p, c_void_p] ! lib.hairpoll_destruct.restype = None lib.hairpoll_destruct.argtypes = [c_void_p] ! lib.hairpoll_add_option.restype = c_int lib.hairpoll_add_option.argtypes = [c_void_p, c_char_p, c_char_p, c_void_p] ! lib.hairpoll_vote.restype = None lib.hairpoll_vote.argtypes = [c_void_p, c_int, c_void_p] ! hairpoll_result_handler = CFUNCTYPE(None, c_void_p, c_char_p, c_int, c_char_p) lib.hairpoll_tally.restype = None lib.hairpoll_tally.argtypes = [c_void_p, hairpoll_result_handler, c_void_p, c_void_p]
  • 44. Summary • Hourglass = C++ on top of C89 on top of C++ • Avoids ABI issues, sneaky dependencies, etc. • Hides object layout and other implementation details • Makes FFI bindings easy