post Image
WindowsのDLLをGoで作る

と銘打っていますが、薄いラッパーを被せてlib*.aをリンクしているのでピュアGoではないです…すいません。

ファイル一式とビルド用Makefileは
nocd5/go_dll_sample
に置いておきます。

背景

Go1.7からWindowsでも-buildmode=c-archiveがサポート予定ですが、
c-sharedは未だサポートされずDLLの作成もできません。
しかし、staticリンク用のインポートライブラリ(lib*.a)が作れるのであれば
それをリンクして簡単にDLLを作れるんじゃないかな~と思ってサンプルを作ってみました。

環境

  • Windows10 HOME 64bit
  • Go 1.7rc3 32bit
  • TDM GCC 5.1.0 32bit

ファイル構成

+--dll
|  +--gofib.cpp
|  +--gofib.def
|
|--exe
|  +--main.cpp
|
+--go-fib
   +--main.go

ファイル構成は上記のようになっています。
exe以下は作成したDLLを読み込むサンプルプログラムなので、DLL作成に必要なのはgo-fib以下とdll以下です。
go-fibはライブラリの本体、dllは薄いラッパーとなっています。

go-fibの中身

Golang で Shared Library を出力する。」から、まるっとコピペさせて頂きましたw

go-fib/main.go
package main

import (
    "C"
    "log"
)

//export fib
func fib(n int) int {
    if n < 2 {
        return n
    }
    return fib(n-2) + fib(n-1)
}

func init() {
    log.Println("Loaded!!")
}

func main() {
}

まぁ御覧の通りフィボナッチです。

dllの中身

ほんとスクリプトとかで生成できるレベルの薄さです

dll/gofib.cpp
#include "libgofib.h"

#ifdef __cplusplus
extern "C" {
#endif

GoInt _fib(GoInt p0) { return fib(p0); }

#ifdef __cplusplus
}
#endif

includeしているlibgofib.hはGoでlibgofib.aビルド時に一緒に自動で生成されるヘッダファイルですので
自分で書く必要はありません。

dll/gofib.def
LIBRARY gofib.dll
EXPORTS
fib = _fib

DEFファイルはラッパー側で_fibの名前で定義した関数をfibで呼び出せるように置いています。

exeの中身

一応DLLを呼び出すサンプルプログラムも記載しておきます。

exe/main.cpp
#include "libgofib.h"
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  if (argc != 2) {
    return 1;
  }
  printf("%d\n", fib(atoi(argv[1])));
}

libgofib.hはラッパーでインクルードしているファイルと同じものです。
“第一引数の値”番目のフィボナッチ数を出力するサンプルです。

ビルド

Goで書かれたライブラリのビルド

pushd go-fib
go build -buildmode=c-archive -o libgofib.a
popd

DLLや実行ファイルリンクじに-lgofibで予備出せるようlibgofib.aという名前で出力しておきます。

これで

  • go-fib/libgofib.a
  • go-fib/libgofib.h

が生成されます。

ラッパーのビルド

pushd dll
gcc -o gofib.dll -mdll gofib.cpp -I../go-fib -L../go-fib -lgofib gofib.def -Wl,--out-implib=libgofib.dll.a -lwinmm -lws2_32 -lntdll
popd

DLL用のインポートライブラリをlibgofib.dll.aという名前で出力しておきます。
dll.aとしている理由は「ダイナミックリンクとスタティックリンクの混在(MinGW環境)」参照。

これで

  • dll/gofib.dll
  • dll/libgofib.dll.a

が生成されます。

サンプルプログラムのビルド

pushd exe
gcc -o main.exe main.cpp -I../go-fib -L../dll -lgofib
popd

これで全て完了です。

exe/main.exe 9

とすれば34が出力されるはずです。

ちなみに、インクルードするヘッダファイルもインポートライブラリの名前も
通常通りstaticリンクする際と共通になるよう合わせてるので

pushd exe
gcc -o main.exe main.cpp -I../go-fib -L../go-fib -lgofib -lwinmm -lws2_32 -lntdll
popd

としてビルドすればDLLではなくスタティックリンクでビルドすることができます。


『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。