試運転 C#からSQLiteを使う
……さてさて、ちゃんと動いてくれるでしょうか。冒頭で示したC++によるサンプルコードをC++/CLIとC#で書いてみました。SQLite3Petiteを参照設定に加えればコンパイル/実行できるはずです。
#include "stdafx.h" using namespace System; using namespace SQLite3Petite; bool print_result(array<String^>^ values, array<String^>^ names) { for ( int i = 0; i < values->Length; ++i ) { System::Console::Write("{0} = [{1}] ", names[i], values[i]); } Console::WriteLine(); return true; } int main() { Database^ db = gcnew Database(); if ( db->open() != Result::OK ) { System::Console::WriteLine( "Error : Can't open database : {0}", db->errmsg()); return 1; } array<String^>^ statements = { L"CREATE TABLE item (id INTEGER PRIMARY KEY, name TEXT NOT NULL, price REAL NOT NULL)", L"INSERT INTO item VALUES ( 1, 'ばなな', 123)", L"INSERT INTO item VALUES ( 2, 'りんご', 234)", L"INSERT INTO item VALUES ( 3, 'みかん', 345)", L"INSERT INTO item VALUES ( 4, 'なし', 456)", L"INSERT INTO item VALUES ( 5, 'もも', 567)", L"INSERT INTO item VALUES ( 6, 'びわ', 789)", L"INSERT INTO item VALUES ( 7, 'くり', 891)", L"CREATE TABLE sales (id INTEGER PRIMARY KEY, quantity NOT NULL )", L"INSERT INTO sales VALUES ( 1, 6 )", L"INSERT INTO sales VALUES ( 3, 4 )", L"INSERT INTO sales VALUES ( 5, 2 )", L"SELECT item.id, name, price, quantity, price*quantity FROM item, sales WHERE item.id = sales.id ORDER BY price*quantity", L"CREATE VIEW named_sales AS SELECT name, quantity FROM sales, item WHERE item.id = sales.id", L"SELECT * FROM named_sales" }; for each ( String^ statement in statements ) { Console::WriteLine(statement); String^ err; if ( db->exec(statement, gcnew Callback(print_result), err) != Result::OK ) { Console::WriteLine(err); return 1; } } return 0; }
using System; using SQLite3Petite; namespace Petite_sample_cs { class Program { static void Main() { Database db = new Database(); if ( db.open() != Result.OK ) { Console.WriteLine("Error : Can't open database : {0}", db.errmsg()); return; } string[] statements = { "CREATE TABLE item (id INTEGER PRIMARY KEY, name TEXT NOT NULL, price REAL NOT NULL)", "INSERT INTO item VALUES ( 1, 'ばなな', 123)", "INSERT INTO item VALUES ( 2, 'りんご', 234)", "INSERT INTO item VALUES ( 3, 'みかん', 345)", "INSERT INTO item VALUES ( 4, 'なし', 456)", "INSERT INTO item VALUES ( 5, 'もも', 567)", "INSERT INTO item VALUES ( 6, 'びわ', 789)", "INSERT INTO item VALUES ( 7, 'くり', 891)", "CREATE TABLE sales (id INTEGER PRIMARY KEY, quantity NOT NULL )", "INSERT INTO sales VALUES ( 1, 6 )", "INSERT INTO sales VALUES ( 3, 4 )", "INSERT INTO sales VALUES ( 5, 2 )", "SELECT item.id, name, price, quantity, price*quantity FROM item, sales WHERE item.id = sales.id ORDER BY price*quantity", "CREATE VIEW named_sales AS SELECT name, quantity FROM sales, item WHERE item.id = sales.id", "SELECT * FROM named_sales" }; foreach ( string statement in statements ) { Console.WriteLine(statement); String err; if ( db.exec(statement, delegate (string[] values, string[] names) { for ( int i = 0; i < values.Length; ++i ) { Console.Write("{0} = [{1}] ", names[i], values[i]); } Console.WriteLine(); return true; }, out err) != Result.OK ) { Console.WriteLine(err); return; } } } } }
まとめ
いかがでしょう、C++/CLIはnative/managed双方の仲介役として機能します。今までに書かれた大量のC/C++コードにC++/CLIで薄皮を被せて.NET化できるわけです。UIをC#やVBのWindows Formsで実装し、C/C++によるビジネスロジックをC++/CLIでUIに接続すれば(おそらくは)最小コストで従来のアプリケーションを.NET世界に組み入れることができそうです。
