scalaからCのプログラムを読みだす

(1)まず準備。
C言語のダイナミックリンクライブラリ(dll)を作る

 #include<stdio.h>
  
   void test_hello(char* v){
  
           printf(v);
  
  }

dll化する

gcc -c test_hello.c

gcc -shared -o test_hello.dll test_hello.o

実行用プログラム

void main(){
        test_hello("This is test");

}

コンパイル

gcc test_dll.c -o test_dll.out -L./ -ltest_hello

実行

./test_dll.out
This is test

関数名とdll名が同じじゃなきゃだめだ。

以下のようにmain関数で定義すれば大丈夫

   void test2();
   void test1(char* v);

   void main(){
          test1("This is test");
          test2();
  }

上記のdllのソース

#include<stdio.h>

void test1(char* v){

        printf(v);
        printf("\n");

}

void test2(){

        printf("hello\n");
}

ちゃんと.hを使って重複を抑えると



test_hello.h

void test1(char* v);
void test2();

test_hello.c

#include<stdio.h>
#include"test_hello.h"

void test1(char* v){

        printf(v);
        printf("\n");

}

void test2(){

        printf("hello\n");
}

main

#include<stdio.h>
#include"test_hello.h"


void main(){
        test1("This is test");
        test2();
}


http://www.sixnine.net/cygwin/translation/cygwin-ug-net/dll.html
http://www.nslabs.jp/cygwin-dll.rhtml
http://exlight.net/devel/windows/dll/windll.html

(2)次にJNA関数でJavaに取り込む
http://www.brainsellers.com/blog/inastream/2011/04/introjna.html
JNAをとってくる

wget https://maven.java.net/content/repositories/releases/net/java/dev/jna/jna/3.5.2/jna-3.5.2.jar … --no-check-certificate
http://d.hatena.ne.jp/mrgoofy33/20110204/1296829185

適当にリネーム

mv jna-3.5.2.jar jna.jar

コンパイル

javac c_test.java -classpath jna-3.5.2.jar

http://d.hatena.ne.jp/ujiujise/20091202/p1 がわかりやすい感じ。。

プログラム
test_hello.h

#ifndef test_hello
#define test_hello

#ifdef _cplusplus
extern "C" {
#endif
        void test1(char* v);
        void test2();
#ifdef _cplusplus
}
#endif
#endif

#ifdef _cplusplus
#endif
c++ のときにif endif内のコードを実行するという意味
extern "C" はC言語の関数を表す

import com.sun.jna.Library;
import com.sun.jna.Native;

public class c_test{



        public interface test_hello extends Library{


                test_hello INSTANCE=(test_hello) Native.loadLibrary("test_hello",test_hello.class);


                void test1(String format);



        }

        public static void main(String[] args){
                test_hello.INSTANCE.test1("Hello World\n");

        }

}

コンパイル

javac c_test -classpath jna.jar

jnaはcygwinに対応していないので,windowsとしてコンパイルする.
mingwを使う


javaWindowsjavaか確認

/cygdrive/c/Windows/system32/java

mingwのインストール

apt-cyg install mingw64-x86_64-gcc-core

コンパイル

x86_64-w64-mingw32-gcc -c test_hello.c
x86_64-w64-mingw32-gcc -shared -o test_hello.dll test_hello.o
x86_64-w64-mingw32-gcc test_dll.c -o test_dll.out -L. -ltest_hello

これでもcygwinでは実行できないので,コマンドプロンプで以下のコマンドで実行

java c_test

アドバイスを受けた人の話だとコンパイラの基礎とかわかってると
色々わかるらしい。
また

jar tf jna.jar 

でどのOSに対応しているか探ることができる
http://choni-waniwani.blogspot.jp/2013/05/playframework211scalajnac.html

scalaで導入

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;

object c_test2{

        def main(args: Array[String]): Unit={

                val lib=NativeLibrary.getInstance("test_hello.dll");
                val func=lib.getFunction("test1");
                func.invokeVoid(Array("test_hello".asInstanceOf[java.lang.String]));


                val func2=lib.getFunction("test2");
                func2.invokeVoid(null);
                //val func2=lib.getFunction("test3");
                //func2.invokeVoid(Array(10.asInstanceOf[java.lang.Integer]));

        }


}


コンパイル

scalac -cp jna.jar c_test2.scala

実行

scala c_test2.scala

結果

test_hello
hello

http://saekiyoshiyasu.org/pblog/programming/java/jna-2009-05-24-22-32.html