AWSで自己署名証明書でうまくいかなかったので,AWSのACM(Amazon Certificate Manager)でプライベートCA機能を使ってみたところ,1ヶ月分の利用料金を課金されてしまいました。気軽に始められるのがクラウドサービスの強みですが,料金をしっかり確認しないとダメですね。AWSが悪いわけではないです。アカウントを乗っ取られて何十万円という料金を請求されたという話も聞いたことがありますので,それと比べれば軽傷でしょう。
ブログ
nodejsとC言語の連携
nodejsとC言語との連携もffi-napiというライブラリを使うと容易に実現できます。このライブラリを導入することの方が時間がかかったくらいです。gccコンパイラが古かったため,コンパイラのアップデートからやる必要がありました。
#!/bin/bash
gcc --shared -fPIC -o libadd.so -xc - << EOS
int add(int x, int y ) { return x + y; }
EOS
cat << EOF > node2c.js
var ffi = require('ffi-napi');
var lib = ffi.Library("libadd", { add: ['int', ['int', 'int']]});
console.log("3 + 4 = "+ lib.add(3, 4));
EOF
node node2c.js

HaskelとC言語の連携
HaskelとC言語との連携もそれほど大変なものではありません。私はほとんどHaskelでの開発をしていないので,Haskelの記法には違和感があります。
#!/bin/bash
gcc --shared -fPIC -o libadd.so -xc - << EOS
int add(int x, int y) { return x + y; }
EOS
cat << EOF > Main.hs
module Main where
import Foreign.C.Types
foreign import ccall "add" c_add :: CInt -> CInt -> CInt
cAdd x y = fromIntegral $ c_add (fromIntegral x) (fromIntegral y)
main :: IO ()
main = do putStrLn "START"
putStrLn ("100 + 200 = " ++ (show(cAdd 100 200)))
putStrLn "END"
EOF
ghc -L. -ladd Main.hs
if [ $? -eq 0 ]; then
./Main
fi

LuaとC言語との連携
LuaとC言語との連携は癖があります。Cライブラリ側にLua専用のコードを記述する必要がありますので,既存のライブラリをそのまま使うという使い方は難しいかもしれません。特にデータの受け渡しは低レベルで,スタックにプッシュしたりポップしたりする手続きを記述する必要があります。
#!/bin/bash
gcc --shared -fPIC -o libadd.so -xc - << EOS
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static int c_add(lua_State *L)
{
lua_pushnumber(L, (luaL_checknumber(L, 1) + luaL_checknumber(L, 2)));
return 1;
}
int luaopen_libadd(lua_State *L)
{
lua_register(L, "add", c_add);
return 0;
}
EOS
if [ ! $? -eq 0 ]; then echo "ERROR" && exit 1; fi
cat << EOF > lua2c.lua
require "libadd"
for i = 1, 10 do
print(tostring(i) .. " + " .. tostring(10 * i) .." = " .. tostring(add(i,i * 10)))
end
EOF
lua lua2c.lua

PHPとC言語の連携
PHPとC言語との連携は非常に簡便に実現できました。但し,PHPのFFIもジュールはバージョン7.4以降のものにしか対応していないようなので,古いPHPでは実行できないかもしれません。
#!/bin/bash
gcc --shared -fPIC -o libadd.so -xc - << EOS
int add(int x, int y) { return x + y; }
EOS
cat << EOF > php2c.php
<?php
\$ffi = FFI::cdef("int add(int, int);", "libadd.so");
print("30 + 40 = " . \$ffi->add(30, 40) . "\n");
?>
EOF
php80 php2c.php

C#とC言語(ネイティブ)の連携
C#とC言語の連携は.NET同士はもちろんのこと,ネイティブなC言語のライブラリでも容易に連携できます。C#のコードにDllImportなどいくつか記述を追加するのみです。Microsoftの以下のドキュメントに詳細に説明されています。
https://learn.microsoft.com/ja-jp/dotnet/framework/interop/creating-prototypes-in-managed-code
#!/bin/bash
rm -rf net2c
dotnet new console -o net2c
cat << EOF > net2c/Program.cs
using System;
using System.Runtime.InteropServices;
public class Net2C
{
[DllImport("libadd.so")]
private static extern int add(int x, int y);
public static void Main(string[] args)
{
Console.WriteLine("START");
Console.WriteLine(add(1,2));
Console.WriteLine("END");
}
}
EOF
gcc --shared -o net2c/libadd.so -xc - << EOS
int add(int x, int y) { return x + y; }
EOS
cd net2c
dotnet build
if [ $? -eq 0 ]; then
dotnet run
fi
cd ..

LispとC言語の連携
Lispはあまり使われていないでしょうけど,一応C言語で作成したライブラリを呼び出せるようです。他と同様にシェルに全部記述しました。
#!/bin/bash
gcc -o libadd.so --shared -fPIC -xc - << EOS
int add(int x, int y) { return x + y; }
EOS
cat << EOF > add.lisp
(ql:quickload :cffi)
(cffi:load-foreign-library "libadd.so")
(defun main ()
(write-line "Lisp START")
(write-line (write-to-string (cffi:foreign-funcall "add" :int 100 :int 200 :int)))
(write-line "Lisp END"))
(sb-ext:save-lisp-and-die "add" :toplevel #'main' :executable t)
EOF
sbcl --load add.lisp
if [ $? -eq 0 ]; then
./add
fi

FORTRANとC言語との連携
FORTRANとCとの連携は少々クセがあります。FORTRANからはポインタが渡されます。また,関数名はFORTRANで定義した関数名に”_”(アンダースコア)を付加したものとなります。私はFORTRAN77の知識しかないため,古い書式です。
#!/bin/bash
gcc -fPIC --shared -xc -o libadd.so - << EOS
#include <stdio.h>
int add_(int* x, int* y, int* z)
{
printf("[C] %d + %d = %d\n", *x, *y, *x + *y);
*z = *x + *y;
return 0;
}
EOS
cat << EOF > fortran01.f
PROGRAM fortran01
IMPLICIT NONE
INTEGER A,B,Z
A = 10
B = 20
WRITE(*,*) 'START'
CALL add(A, B, Z)
WRITE(*,100) A, B, Z
WRITE(*,*) 'END'
100 FORMAT('[FORTRAN]', I5, ' + ', I5, ' = ', I5)
STOP
END
EOF
gfortran -o fortran01 fortran01.f libadd.so
./fortran01

PerlとC言語の連携
PerlからC言語のライブラリを呼び出すのは少々厄介でした。h2xsというツールを使ってテンプレートを生成した上で作成されたMakefileを使ってビルドするという手順になります。他の記事に倣ってシェル1本で書いたので,苦しい対処ですが,sedコマンドとcatコマンドでで生成されたテンプレートを編集しています。
#!/bin/bash
rm -rf Perl2C
h2xs -A -n Perl2C
source=Perl2C/Perl2C.xs
sed -i -e 's/^MODULE.*$/int add(int,int);\n\nMODULE = Perl2C PACKAGE = Perl2C/g' $source
cat << EOS >> $source
int
add(x, y)
int x
int y
CODE:
RETVAL = x + y;
OUTPUT:
RETVAL
EOS
echo "========================================"
cat $source
echo "========================================"
cd Perl2C
perl Makefile.PL
make
cat << EOF > run.pl
use ExtUtils::testlib;
use Perl2C;
\$x = 1000;
\$y = 2000;
\$result = Perl2C::add(\$x, \$y);
print(\$x . " + " . \$y . " = " . \$result . "\n\n");
EOF
perl run.pl
cd ..

Gnu COBOLとC言語との連携
Gnu COBOLとC言語との連携は比較的容易に実現できます。Gnu COBOL自体がCOBOLのソースコードをC言語に変換してからCコンパイラでコンパイルするというアーキテクチャで実現されていることも理由と思われます。
Cプログラムは普通にライブラリを作成する要領で作成できます。COBOLからはCALL文でサブルーチンを呼ぶのと同じです。文字列の扱いはCOBOL文字列をそのままCライブラリに渡しても処理ができないため,末尾に’\0’を付加して渡す必要があります。
#!/bin/bash
gcc -fPIC --shared -o add.so -xc - << EOF
int add(int x, int y)
{
return x + y;
}
EOF
cat << EOS > cob01.cob
000100**************************************************************************
000200 IDENTIFICATION DIVISION.
000300 PROGRAM-ID. PROGRAM01.
000400 AUTHOR. KUBO, Y.
000500**************************************************************************
000600 ENVIRONMENT DIVISION.
000700**************************************************************************
000800 DATA DIVISION.
000900*-------------------------------------------------------------------------
001000 WORKING-STORAGE SECTION.
001100*-------------------------------------------------------------------------
001200 01 WORK.
001300 03 WORK-ARG1 PIC 9(06) VALUE ZERO.
001400 03 WORK-ARG2 PIC 9(06) VALUE ZERO.
001500 01 RET PIC 9(04) COMP-X.
001600**************************************************************************
001700 PROCEDURE DIVISION.
001800**************************************************************************
001900 MAIN-RTN.
002000 DISPLAY 'START'.
002100 MOVE 100 TO WORK-ARG1.
002220 MOVE 200 TO WORK-ARG2.
002300 CALL 'add' USING BY VALUE WORK-ARG1
002400 BY VALUE WORK-ARG2
002500 RETURNING RET.
002600 DISPLAY RET.
002700 DISPLAY 'END'.
002800 STOP RUN.
002900**************************************************************************
EOS
cobc -x -o cob01 cob01.cob
./cob01
