Saya memiliki pustaka C ++ yang menyediakan berbagai kelas untuk mengelola data. Saya memiliki kode sumber untuk perpustakaan.
Saya ingin memperluas C ++ API untuk mendukung pemanggilan fungsi C sehingga perpustakaan dapat digunakan dengan kode C dan kode C ++ pada saat yang bersamaan.
Saya menggunakan rantai alat GNU (gcc, glibc, dll), jadi dukungan bahasa dan arsitektur tidak menjadi masalah.
Apakah ada alasan mengapa hal ini secara teknis tidak memungkinkan?
Apakah ada gotcha yang perlu saya waspadai?
Apakah ada sumber daya, kode contoh dan / atau dokumentasi yang tersedia tentang ini?
Beberapa hal lain yang saya temukan:
- Gunakan perintah berikut untuk menggabungkan header C ++ Anda yang perlu digunakan oleh kode C.
#ifdef __cplusplus
extern "C" {
#endif
//
// Code goes here ...
//
#ifdef __cplusplus
} // extern "C"
#endif
- Pertahankan antarmuka C ++ "asli" di file header terpisah yang tidak disertakan oleh C. Pikirkan prinsip PIMPL di sini. Menggunakan
#ifndef __cplusplus #error
barang membantu di sini untuk mendeteksi kegilaan. - Hati-hati dengan pengenal C ++ sebagai nama dalam kode C.
- Enum memiliki ukuran yang bervariasi antara compiler C dan C ++. Mungkin bukan masalah jika Anda menggunakan rantai alat GNU, tapi tetap berhati-hatilah.
Untuk struct, ikuti formulir berikut agar C tidak bingung.
typedef struct X { ... } X
Kemudian gunakan pointer untuk meneruskan objek C ++, mereka hanya harus dideklarasikan di C sebagai struct X di mana X adalah objek C ++.
Semua ini adalah milik seorang teman yang merupakan ahli sihir di C ++.
Jawaban:
Ya, ini pasti mungkin. Anda perlu menulis lapisan antarmuka dalam C ++ yang mendeklarasikan fungsi dengan
extern "C"
:Kemudian, Anda akan memanggil
foo()
dari modul C Anda, yang akan meneruskan panggilan kerealFoo()
fungsi yang diimplementasikan di C ++.Jika Anda perlu mengekspos kelas C ++ lengkap dengan anggota data dan metode, Anda mungkin perlu melakukan lebih banyak pekerjaan daripada contoh fungsi sederhana ini.
sumber
extern "C"
ditempatkan hanya dalam deklarasi (dan bukan dalam definisi)? Karena Anda menyebutkan "lapisan yang mendeklarasikan fungsi" tetapi kode sampel Anda juga merupakan definisi. Dengan kata lain, haruskah kita menempatkannya di file header atau file sumber? (Atau keduanya?)extern "C"
sana. Kompiler Anda akan memberi tahu Anda jika Anda juga harus meletakkannya pada definisi.C ++ FAQ Lite: "Cara mencampur kode C dan C ++" .
Beberapa gotcha dijelaskan dalam jawaban atas pertanyaan-pertanyaan ini:
sumber
Gotcha utama: pengecualian tidak dapat ditangkap di C. Jika ada kemungkinan pengecualian muncul dalam kode C ++, tulis kode C atau pembungkus C ++ Anda dengan sangat hati-hati. Sebaliknya, pengecualian seperti mekanisme (yaitu, longjump) dalam kode C (seperti yang ditemukan dalam berbagai bahasa skrip) tidak diperlukan untuk memanggil destruktor untuk objek C ++ pada tumpukan.
sumber
Anda dapat mencampur kode C / C ++. Jika main () berfungsi di C ++, maka Anda hanya perlu memastikan fungsi c Anda dideklarasikan
Jika utama Anda adalah C, maka Anda mungkin baik-baik saja kecuali untuk variabel statis. Setiap konstruktor dengan variabel statis Anda seharusnya dipanggil sebelum main () start. Ini tidak akan terjadi jika C adalah utama Anda. Jika Anda memiliki banyak variabel statis, hal terbaik yang harus dilakukan adalah mengganti variabel statis dengan lajang.
sumber