Topik ini membahas interop antara COBOL dan C pada GnuCOBOL, mulai dari bukti bahwa cobc menerjemahkan COBOL menjadi C, pemanggilan rutin C dengan CALL USING, sampai kecocokan tipe data pada batas kedua bahasa. Sebagai contoh, sebuah fungsi C yang mengubah isi field menjadi huruf besar dipanggil dari program COBOL, dikompilasi dengan satu perintah cobc bersama kode COBOL-nya, lalu dijalankan. Pemahaman ini menjadi dasar ketika program COBOL perlu memanfaatkan pustaka C yang sudah tersedia pada sistem.
cobc menerjemahkan COBOL menjadi C#
cobc bekerja dalam dua tahap, yaitu menerjemahkan kode sumber COBOL menjadi kode C, kemudian menyerahkan hasil terjemahan itu kepada compiler C seperti gcc untuk dijadikan program yang dapat dieksekusi. Tahap pertama dapat diamati secara langsung dengan bendera -C, yang menyuruh cobc berhenti setelah menghasilkan berkas C tanpa melanjutkan ke kompilasi. Perintah berikut menerjemahkan panggil.cbl, kemudian ls memeriksa bahwa hasil terjemahannya tersedia pada direktori yang sama.
# terjemahkan COBOL menjadi C dan berhenti sebelum kompilasi
cobc -C panggil.cbl
# pastikan berkas hasil terjemahan tersedia
ls panggil.cpanggil.ccobc sebenarnya menghasilkan panggil.c bersama berkas header pendampingnya, dan berkas panggil.c itulah yang diteruskan kepada compiler C pada kompilasi normal. Cuplikan berikut diambil langsung dari panggil.c dan memperlihatkan wujud program COBOL setelah diterjemahkan.
// tidak-dijalankan
/* ENTRY 'PANGGIL' */
int
PANGGIL ()
{
return PANGGIL_ (0);
}Program COBOL dengan PROGRAM-ID PANGGIL menjadi fungsi C bernama PANGGIL, sedangkan pernyataan-pernyataan di dalamnya diterjemahkan menjadi pemanggilan pustaka runtime libcob, misalnya cob_display untuk DISPLAY. Karena kode COBOL berubah menjadi kode C, interop dengan C menjadi hal yang wajar bagi GnuCOBOL, bukan lapisan tambahan yang terpisah.
Memanggil rutin C dengan CALL#
Pernyataan CALL memanggil rutin luar dengan bentuk CALL "nama" USING item-1 item-2, dan setiap item pada USING dikirimkan by reference secara default, artinya rutin yang dipanggil menerima pointer ke storage aslinya. Nama pada literal CALL dilipat menjadi huruf kecil oleh cobc, sehingga nama fungsi C yang dipanggil harus ditulis dengan huruf kecil semua.
Rutin C berikut menerima pointer ke byte teks dan pointer ke panjangnya, lalu mengubah setiap byte menjadi huruf besar. Nilai kembaliannya ditetapkan bernilai 0 karena GnuCOBOL menjadikan nilai kembalian fungsi C sebagai RETURN-CODE program pemanggil.
// tidak-dijalankan
/* Rutin C yang dipanggil dari COBOL: ubah byte teks menjadi huruf besar. */
#include <ctype.h>
int hurufbesar(unsigned char *teks, unsigned short *panjang)
{
unsigned short i;
for (i = 0; i < *panjang; i++) {
teks[i] = (unsigned char) toupper(teks[i]);
}
return 0;
}Program COBOL berikut menyiapkan teks dan panjangnya, memanggil hurufbesar, lalu menampilkan isi field sebelum dan sesudah pemanggilan. Field TEKS-UJI berukuran 11 karakter, sehingga 11 dikirim sebagai panjang dan tidak ada pemindaian melewati batas field.
IDENTIFICATION DIVISION.
PROGRAM-ID. PANGGIL.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TEKS-UJI PIC X(11) VALUE "cobol dan c".
01 PANJANG-TEKS PIC 9(4) COMP-5.
PROCEDURE DIVISION.
MOVE 11 TO PANJANG-TEKS
DISPLAY "SEBELUM : " TEKS-UJI
CALL "hurufbesar" USING TEKS-UJI PANJANG-TEKS
DISPLAY "SESUDAH : " TEKS-UJI
STOP RUN.SEBELUM : cobol dan c
SESUDAH : COBOL DAN CKompilasi kedua berkas dalam satu perintah berikut.
# kompilasi program COBOL bersama rutin C dalam satu perintah
cobc -x panggil.cbl rutin.cJalankan ./panggil dan bandingkan kedua baris keluarannya. Isi TEKS-UJI berubah di tempat tanpa variabel penampung baru, karena rutin C menulis langsung ke storage COBOL melalui pointer yang diterimanya.
Kecocokan tipe pada batas bahasa#
Kesalahan interop hampir selalu bermula dari ketidakcocokan tipe, karena itu pasangan parameter pada USING harus dipadankan dengan parameter C secara eksplisit. Tabel berikut merangkum padanan yang dipakai pada contoh topik ini.
| Field COBOL | Parameter C | Sifat penyimpanannya |
|---|---|---|
TEKS-UJI PIC X(11) | unsigned char * | 11 byte berurutan, tanpa null terminator |
PANJANG-TEKS PIC 9(4) COMP-5 | unsigned short * | biner dua byte sesuai ukuran COMP-5 |
Field PIC X adalah deretan byte berpanjang tetap yang diisi spasi pada bagian tak terpakai, bukan string C yang diakhiri karakter null. Rutin C tidak dapat menentukan panjang dengan mencari karakter null karena karakter itu tidak ada, sehingga panjang dikirim sebagai parameter terpisah sebagaimana PANJANG-TEKS. Item COMP-5 menyimpan nilai biner dengan ukuran alami sesuai jumlah digitnya, yaitu dua byte untuk 1 sampai 4 digit, dan parameter C-nya bertipe unsigned short agar lebarnya sama persis. Pengiriman by reference juga menjelaskan sifat contoh ini, yaitu perubahan yang dilakukan rutin C berlaku pada storage COBOL aslinya, bukan pada salinannya. Padanan pada tabel mengikuti perilaku bawaan GnuCOBOL 3.2 di Linux, sedangkan tata letak byte field numerik dapat berbeda pada compiler lain, sehingga tabel tersebut perlu diperiksa ulang ketika rutin dipindahkan ke lingkungan lain.
Kesalahan umum#
Nama fungsi C tidak ditulis huruf kecil semua. Kompilasi tetap berhasil karena pencocokan nama dilakukan pada saat program dijalankan, dan pemanggilan berakhir dengan
libcob: error: module 'hurufbesar' not found. Tulis nama fungsi C dengan huruf kecil agar cocok dengan pelipatan nama pada literal CALL.Panjang string ditentukan di sisi C dengan pencarian karakter null. Field PIC X diisi spasi dan tidak pernah diakhiri null, sehingga pencarian itu membaca melewati batas field. Kirim panjang sebagai parameter terpisah sebagaimana PANJANG-TEKS.
Parameter C berukuran tidak sama dengan field COBOL, misalnya
intempat byte untuk field COMP-5 dua byte. Nilai yang terbaca menjadi kacau, dan ciri umum kegagalan ini adalah angka yang melompat tanpa pola. Padankan tipe C dengan ukuran storage field COBOL.Fungsi C ditulis tanpa nilai kembalian yang jelas. Nilai kembalian fungsi menjadi RETURN-CODE program pemanggil, sehingga program pemanggil dapat menerima nilai sisa register yang tidak terduga. Kembalikan int 0 pada keberhasilan.
Ringkasan#
- cobc menerjemahkan COBOL menjadi C lalu memanggil compiler C, dan bendera
-Cmenghasilkan berkas .c yang dapat dibaca. - CALL dengan USING mengirim parameter by reference secara default, sehingga rutin C menerima pointer dan dapat mengubah storage COBOL aslinya.
- Nama pada literal CALL dilipat menjadi huruf kecil, sehingga nama fungsi C ditulis huruf kecil semua.
- String COBOL berpanjang tetap dan berisi spasi pengisi tanpa null terminator, sehingga panjangnya dikirim sebagai parameter terpisah.
Referensi#
- GnuCOBOL Manual — GnuCOBOL project — pernyataan CALL, opsi -C, dan alur kerja cobc dari COBOL menuju C.
- GnuCOBOL — Free Software Foundation — situs proyek GnuCOBOL dengan pengumuman rilis 3.2 dan tautan dokumentasinya.