Created
May 24, 2019 03:58
-
-
Save caiorss/c236aedbbb514717ad26e856654bb063 to your computer and use it in GitHub Desktop.
Example - Calling C++ from C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.9) | |
project( CallCppFromC) | |
set(CMAKE_CXX_STANDARD 17) | |
set(CMAKE_VERBOSE_MAKEFILE ON) | |
add_executable(main main.c codecpp.cpp codecpp.hpp) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "codecpp.hpp" | |
#include <iostream> | |
#include <vector> | |
#include <string> | |
#include <cmath> | |
//----------- Implementation of class RunningStatics -----------// | |
Runstat::Runstat() | |
{ | |
std::cout << " [TRACE] Object created Ok." << std::endl; | |
m_sum = 0.0; | |
m_sumsq = 0.0; | |
m_N = 0; | |
} | |
Runstat::~Runstat() | |
{ | |
std::cout << " [TRACE] Object deleted OK" << std::endl; | |
} | |
void | |
Runstat::add(double x) | |
{ | |
m_sum += x; | |
m_sumsq += x * x; | |
m_N++; | |
} | |
size_t | |
Runstat::size() const | |
{ | |
return m_N; | |
} | |
void | |
Runstat::reset() | |
{ | |
m_sum = 0.0; | |
m_sumsq = 0.0; | |
m_N = 0; | |
} | |
double | |
Runstat::mean() const | |
{ | |
return m_sum / m_N; | |
} | |
double | |
Runstat::sdev() const | |
{ | |
size_t N = m_N; | |
return std::sqrt((m_sumsq - m_sum * m_sum / N) / (N - 1.0)); | |
} | |
//--------- C-Interface for class std::string ------------------// | |
hString string_new() | |
{ | |
return new std::string{}; | |
} | |
hString string_new1(const char* text) | |
{ | |
return new std::string(text); | |
} | |
// Copy constructor | |
hString string_copy(hString self) | |
{ | |
std::string* p = reinterpret_cast<std::string*>(self); | |
return new std::string(*p); | |
} | |
void string_del(hString self) | |
{ | |
delete reinterpret_cast<std::string*>(self); | |
} | |
void string_add(hString self, const char* text) | |
{ | |
auto p = reinterpret_cast<std::string*>(self); | |
*p = *p + text; | |
} | |
void string_disp(hString self, const char* name) | |
{ | |
auto p = reinterpret_cast<std::string*>(self); | |
std::cout << name << " / std::string{ " << *p << "} " << std::endl; | |
} | |
//---------- C-Interface for class Runstat ---------------------// | |
pStat Runstat_new() | |
{ | |
return new (std::nothrow) Runstat(); | |
} | |
void Runstat_del(pStat self) | |
{ | |
delete reinterpret_cast<Runstat*>(self); | |
} | |
void Runstat_add(pStat self, double x) | |
{ | |
auto p = reinterpret_cast<Runstat*>(self); | |
p->add(x); | |
} | |
double Runstat_mean(pStat self) | |
{ | |
Runstat* p = reinterpret_cast<Runstat*>(self); | |
return p->mean(); | |
} | |
double Runstat_sdev(pStat self) | |
{ | |
Runstat* p = reinterpret_cast<Runstat*>(self); | |
return p->sdev(); | |
} | |
size_t Runstat_size(pStat self) | |
{ | |
Runstat* p = reinterpret_cast<Runstat*>(self); | |
return p->size(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _CODECPP_ | |
#define _CODECPP_ | |
#ifdef __cplusplus | |
#define EXPORT_C extern "C" | |
#else | |
#define EXPORT_C | |
#endif | |
//============ C++ Only Header =================// | |
#ifdef __cplusplus | |
#include <iostream> | |
class Runstat | |
{ | |
/// Sum of sequence processed | |
double m_sum; | |
/// Sum of squares processed | |
double m_sumsq; | |
/// Size of sequence processed | |
size_t m_N; | |
public: | |
Runstat(); | |
Runstat(Runstat const&) = delete; | |
Runstat& operator=(Runstat const&) = delete; | |
~Runstat(); | |
void add(double x); | |
void reset(); | |
size_t size() const; | |
double mean() const; | |
/// Standard deviation | |
double sdev() const; | |
}; | |
#endif //-- End of __cplusplus definition // | |
// ========== C-interface for std::string container | |
typedef void* hString; | |
EXPORT_C hString string_new(); | |
EXPORT_C hString string_new1 (const char* text); | |
EXPORT_C hString string_copy (hString self); | |
EXPORT_C void string_del (hString self); | |
EXPORT_C void string_add (hString self, const char* text); | |
EXPORT_C void string_disp (hString, const char* name); | |
//============ C-interface for class Runstat ============// | |
// Opaque pointer type alias for C-lang | |
typedef void* pStat; | |
EXPORT_C pStat Runstat_new(); | |
EXPORT_C void Runstat_del (pStat self); | |
EXPORT_C void Runstat_add (pStat self, double x); | |
EXPORT_C double Runstat_mean(pStat self); | |
EXPORT_C double Runstat_sdev(pStat self); | |
EXPORT_C size_t Runstat_size(pStat self); | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include "codecpp.hpp" | |
int main() | |
{ | |
printf("\n == EXPERIMENT 1 - std::string C-wrapper ======\n"); | |
hString str = string_new1("A C++ string in C"); | |
string_disp(str, "str"); | |
hString str2 = string_copy(str); | |
string_add(str, " - hello world"); | |
string_disp(str, "str"); | |
string_disp(str2, "str2"); | |
string_del(str); | |
string_del(str2); | |
printf("\n == EXPERIMENT 2 - Class Runstat ======\n"); | |
pStat obj = Runstat_new(); | |
Runstat_add(obj, 10.0); | |
Runstat_add(obj, 4.0); | |
Runstat_add(obj, 25.0); | |
Runstat_add(obj, 16.0); | |
printf(" Number of Elements processed = %zu \n", Runstat_size(obj)); | |
printf(" Mean = %.5f \n", Runstat_mean(obj)); | |
printf(" Sdev = %.5f \n", Runstat_sdev(obj)); | |
Runstat_add(obj, -50.0); | |
Runstat_add(obj, 80.0); | |
printf(" Mean = %.5f \n", Runstat_mean(obj)); | |
printf(" Sdev = %.5f \n", Runstat_sdev(obj)); | |
// Delete C++ Object | |
Runstat_del(obj); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ ./main.bin | |
== EXPERIMENT 1 - std::string C-wrapper ====== | |
str / std::string{ A C++ string in C} | |
str / std::string{ A C++ string in C - hello world} | |
str2 / std::string{ A C++ string in C} | |
== EXPERIMENT 2 - Class Runstat ====== | |
[TRACE] Object created Ok. | |
Number of Elements processed = 4 | |
Mean = 13.75000 | |
Sdev = 8.95824 | |
Mean = 14.16667 | |
Sdev = 41.69612 | |
[TRACE] Object deleted OK |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment