Last active
June 13, 2026 05:12
-
-
Save kuc-arc-f/b6df48e804989401ea09d9f0fb24198b to your computer and use it in GitHub Desktop.
GoLang call C++ , plugin package
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module go-cpp-plugin-demo | |
| go 1.26.1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Go の plugin パッケージを使用して C++ .so プラグインをロードし、 | |
| // 文字列を C++ に送信して、処理結果を受け取るデモプログラム。 | |
| package main | |
| import ( | |
| "fmt" | |
| "os" | |
| "plugin" | |
| "strings" | |
| ) | |
| const pluginPath = "./myplugin/myplugin.so" | |
| func main() { | |
| fmt.Println(strings.Repeat("=", 60)) | |
| fmt.Println(" Go ⇄ C++ プラグイン通信デモ") | |
| fmt.Println(" (plugin パッケージ使用)") | |
| fmt.Println(strings.Repeat("=", 60)) | |
| // ── プラグインのロード ── | |
| fmt.Printf("\n📦 プラグインをロード中: %s\n", pluginPath) | |
| p, err := plugin.Open(pluginPath) | |
| if err != nil { | |
| fmt.Fprintf(os.Stderr, "❌ プラグインのロードに失敗: %v\n", err) | |
| os.Exit(1) | |
| } | |
| fmt.Println("✅ プラグインのロード成功") | |
| // ── 関数のルックアップ ── | |
| processStringSym, err := p.Lookup("ProcessString") | |
| if err != nil { | |
| fmt.Fprintf(os.Stderr, "❌ ProcessString のルックアップに失敗: %v\n", err) | |
| os.Exit(1) | |
| } | |
| processString, ok := processStringSym.(func(string) string) | |
| if !ok { | |
| fmt.Fprintf(os.Stderr, "❌ ProcessString の型が不正\n") | |
| os.Exit(1) | |
| } | |
| toUpperSym, err := p.Lookup("ToUpper") | |
| if err != nil { | |
| fmt.Fprintf(os.Stderr, "❌ ToUpper のルックアップに失敗: %v\n", err) | |
| os.Exit(1) | |
| } | |
| toUpper, ok := toUpperSym.(func(string) string) | |
| if !ok { | |
| fmt.Fprintf(os.Stderr, "❌ ToUpper の型が不正\n") | |
| os.Exit(1) | |
| } | |
| stringInfoSym, err := p.Lookup("StringInfo") | |
| if err != nil { | |
| fmt.Fprintf(os.Stderr, "❌ StringInfo のルックアップに失敗: %v\n", err) | |
| os.Exit(1) | |
| } | |
| stringInfo, ok := stringInfoSym.(func(string) string) | |
| if !ok { | |
| fmt.Fprintf(os.Stderr, "❌ StringInfo の型が不正\n") | |
| os.Exit(1) | |
| } | |
| // ── テストメッセージの送受信 ── | |
| messages := []string{ | |
| "Hello, C++!", | |
| "こんにちは世界", | |
| "Go から C++ へ文字列送信テスト", | |
| "ABCDE 12345", | |
| } | |
| // 1. ProcessString(文字列反転) | |
| fmt.Println("\n" + strings.Repeat("-", 60)) | |
| fmt.Println("📝 テスト1: 文字列処理 (ProcessString)") | |
| fmt.Println(strings.Repeat("-", 60)) | |
| for _, msg := range messages { | |
| fmt.Printf("\n Go → C++: \"%s\"\n", msg) | |
| result := processString(msg) | |
| fmt.Printf(" C++ → Go: %s\n", result) | |
| } | |
| // 2. ToUpper(大文字変換) | |
| fmt.Println("\n" + strings.Repeat("-", 60)) | |
| fmt.Println("📝 テスト2: 大文字変換 (ToUpper)") | |
| fmt.Println(strings.Repeat("-", 60)) | |
| for _, msg := range messages { | |
| fmt.Printf("\n Go → C++: \"%s\"\n", msg) | |
| result := toUpper(msg) | |
| fmt.Printf(" C++ → Go: %s\n", result) | |
| } | |
| // 3. StringInfo(文字列情報) | |
| fmt.Println("\n" + strings.Repeat("-", 60)) | |
| fmt.Println("📝 テスト3: 文字列情報 (StringInfo)") | |
| fmt.Println(strings.Repeat("-", 60)) | |
| for _, msg := range messages { | |
| fmt.Printf("\n Go → C++: \"%s\"\n", msg) | |
| result := stringInfo(msg) | |
| fmt.Printf(" C++ → Go: %s\n", result) | |
| } | |
| fmt.Println("\n" + strings.Repeat("=", 60)) | |
| fmt.Println(" ✅ すべてのテスト完了") | |
| fmt.Println(strings.Repeat("=", 60)) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| .PHONY: all plugin main run clean | |
| # デフォルト: プラグインとメインプログラムの両方をビルド | |
| all: plugin main | |
| # Go プラグイン (.so) のビルド | |
| # C++ ソースコードは cgo によって自動的にコンパイルされる | |
| plugin: | |
| @echo "🔨 プラグインをビルド中..." | |
| cd myplugin && go build -buildmode=plugin -o myplugin.so . | |
| @echo "✅ myplugin/myplugin.so を生成しました" | |
| # メインプログラムのビルド | |
| main: | |
| @echo "🔨 メインプログラムをビルド中..." | |
| go build -o app main.go | |
| @echo "✅ app を生成しました" | |
| # ビルドして実行 | |
| run: all | |
| @echo "" | |
| @echo "🚀 実行中..." | |
| @echo "" | |
| ./app | |
| # クリーンアップ | |
| clean: | |
| @echo "🧹 クリーンアップ中..." | |
| rm -f app myplugin/myplugin.so | |
| @echo "✅ 完了" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Package main は Go plugin として C++ の文字列処理関数をエクスポートする。 | |
| // go build -buildmode=plugin でビルドし、メインプログラムから plugin パッケージで読み込む。 | |
| package main | |
| /* | |
| #cgo CXXFLAGS: -std=c++17 -O2 | |
| #cgo LDFLAGS: -lstdc++ | |
| #include "processor.h" | |
| #include <stdlib.h> | |
| */ | |
| import "C" | |
| import "unsafe" | |
| // ProcessString は Go の文字列を C++ に送信し、処理結果を受け取って返す。 | |
| // C++ 側で文字列の反転処理が行われる。 | |
| func ProcessString(msg string) string { | |
| cMsg := C.CString(msg) | |
| defer C.free(unsafe.Pointer(cMsg)) | |
| cResult := C.process_string(cMsg) | |
| defer C.free_string(cResult) | |
| return C.GoString(cResult) | |
| } | |
| // ToUpper は Go の文字列を C++ に送信し、大文字変換結果を受け取って返す。 | |
| func ToUpper(msg string) string { | |
| cMsg := C.CString(msg) | |
| defer C.free(unsafe.Pointer(cMsg)) | |
| cResult := C.to_upper(cMsg) | |
| defer C.free_string(cResult) | |
| return C.GoString(cResult) | |
| } | |
| // StringInfo は Go の文字列を C++ に送信し、文字列情報を受け取って返す。 | |
| func StringInfo(msg string) string { | |
| cMsg := C.CString(msg) | |
| defer C.free(unsafe.Pointer(cMsg)) | |
| cResult := C.string_info(cMsg) | |
| defer C.free_string(cResult) | |
| return C.GoString(cResult) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "processor.h" | |
| #include <cstring> | |
| #include <cstdlib> | |
| #include <string> | |
| #include <algorithm> | |
| #include <sstream> | |
| #include <cctype> | |
| extern "C" { | |
| // Go から受け取った文字列を処理し、反転した結果と合わせて返す | |
| char* process_string(const char* input) { | |
| std::string str(input); | |
| // 文字列を反転(UTF-8 バイト単位) | |
| std::string reversed(str.rbegin(), str.rend()); | |
| // 結果を組み立て | |
| std::string result = "[C++ 処理結果] 受信: \"" + str + "\" → 反転: \"" + reversed + "\""; | |
| // malloc で確保して返す(Go 側で free_string を呼ぶ) | |
| char* output = (char*)malloc(result.length() + 1); | |
| std::strcpy(output, result.c_str()); | |
| return output; | |
| } | |
| // 文字列を大文字に変換して返す(ASCII 部分のみ) | |
| char* to_upper(const char* input) { | |
| std::string str(input); | |
| std::string upper_str; | |
| upper_str.reserve(str.size()); | |
| for (char c : str) { | |
| upper_str += static_cast<char>(std::toupper(static_cast<unsigned char>(c))); | |
| } | |
| std::string result = "[C++ 大文字変換] \"" + std::string(input) + "\" → \"" + upper_str + "\""; | |
| char* output = (char*)malloc(result.length() + 1); | |
| std::strcpy(output, result.c_str()); | |
| return output; | |
| } | |
| // 文字列の情報(バイト数、ASCII 文字数)を返す | |
| char* string_info(const char* input) { | |
| std::string str(input); | |
| size_t byte_count = str.size(); | |
| size_t ascii_count = 0; | |
| size_t non_ascii_count = 0; | |
| for (unsigned char c : str) { | |
| if (c < 128) { | |
| ascii_count++; | |
| } else { | |
| non_ascii_count++; | |
| } | |
| } | |
| std::ostringstream oss; | |
| oss << "[C++ 文字列情報] \"" << str << "\"" | |
| << " | バイト数: " << byte_count | |
| << " | ASCII文字数: " << ascii_count | |
| << " | 非ASCII バイト数: " << non_ascii_count; | |
| std::string result = oss.str(); | |
| char* output = (char*)malloc(result.length() + 1); | |
| std::strcpy(output, result.c_str()); | |
| return output; | |
| } | |
| // malloc で確保したメモリを解放する | |
| void free_string(char* str) { | |
| if (str != nullptr) { | |
| free(str); | |
| } | |
| } | |
| } // extern "C" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef PROCESSOR_H | |
| #define PROCESSOR_H | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif | |
| // Go から受け取った文字列を処理し、結果を返す | |
| char* process_string(const char* input); | |
| // 文字列を大文字に変換して返す | |
| char* to_upper(const char* input); | |
| // 文字列の情報(長さ、バイト数など)を返す | |
| char* string_info(const char* input); | |
| // 返却された文字列のメモリを解放する | |
| void free_string(char* str); | |
| #ifdef __cplusplus | |
| } | |
| #endif | |
| #endif // PROCESSOR_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment