''[[FrontPage]]''
* visual studioでDLLを作成する [#w92fcb16]
C言語で書いたコードをTclから呼び出すTcl拡張を、visual studioを用いてDLLを作成し、実現します。~
ソースコード中のコメントとプロジェクトのキャプチャを参考に試してみてください。~
** 制約事項 [#ea4fe6e8]
visual studioで開発していくことを前提とする。~
~
~
#ref(http://bj006.com/images/c++_tcl_dll_090502_01.png)
#ref(http://bj006.com/images/c++_tcl_dll_090502_02.png)
#ref(http://bj006.com/images/c++_tcl_dll_090502_03.png)
#ref(http://bj006.com/images/c++_tcl_dll_090502_04.png)
[[おまけ - プリコンパイル済みヘッダを使用する(上):http://bj006.com/images/c++_tcl_dll_090502_05.png]]~
[[おまけ - プリコンパイル済みヘッダを使用する(中):http://bj006.com/images/c++_tcl_dll_090502_06.png]]~
[[おまけ - プリコンパイル済みヘッダを使用する(下):http://bj006.com/images/c++_tcl_dll_090502_07.png]]~
ファイル名:StyleDll.h
#ifndef STYLE_DLL // //
#define STYLE_DLL // //
// //
#define USE_TCL_STUBS 1 // スタブ機構を使用する //
// //
extern "C" // C言語としての実装を宣言(必要?) //
{ // //
__declspec( dllexport ) s4 Dlltest_Init( Tcl_Interp* interp ); // DLL内の関数を外部に公開する //
} // //
// //
#endif // STYLE_DLL //
ファイル名:StyleDll.cpp
#include "X:\XXXXX\XXXXXX\XXXXXXXX\pch.h" // プリコンパイル済ヘッダ //
#include "./StyleDll.h" // 個別ヘッダファイル //
// //
/* DLL Test ***************************************************//* Dllテスト関数 */
static s4 dllTest( ClientData clientData, // //
Tcl_Interp *interp, // //
s4 objc, // //
Tcl_Obj * CONST objv[] ) // //
{ // //
s4 rntCod = TCL_OK; // リターンコード //
// //
Tcl_AppendResult( interp, // Tclインタープリタに文字列を返す //
objv[ZERO]->bytes, // コマンド名 //
" is called. arg1 is ", // 編集 //
objv[ONE]->bytes, NULL ); // 渡された引数の1番目 //
// //
return( rntCod ); // 正常終了 //
} // //
//*DLL Test ***************************************************//* Dllテスト関数 */
/* Initialize DLL Test ****************************************//* Dllテスト関数初期化 */
s4 Dlltest_Init( Tcl_Interp *interp ) // //
{ // //
s4 rntCod = TCL_OK; // リターンコード //
// //
for( ; ; ) // 無限ループ //
{ // //
if( NULL == Tcl_InitStubs( interp, "8.1", ZERO ) ) // スタブ機構を準備 //
{ // スタブ機構の準備に失敗したら //
rntCod = TCL_ERROR; // リターンコードに異常を設定 //
break; // 処理中断 //
} // //
// //
Tcl_CreateObjCommand( interp, "Dlltest", dllTest, NULL, NULL ); // Tcl拡張コマンドを登録 //
} // //
// //
return( rntCod ); // リターンコードを戻して処理終了 //
} // //
//*Initialize DLL Test ****************************************//* Dllテスト関数初期化 */
ファイル名:pch.cpp
#include "X:\XXXXX\XXXXXX\XXXXXXXX\pch.h" // プリコンパイル済みヘッダを指定 //
// //
ファイル名:pch.h
#include "./comm.h" // 共通ヘッダをプリコンパイル //
ファイル名:comm.h
#ifndef COMM_H // //
#define COMM_H // //
// //
//#pragma comment( lib, "wsock32.lib" ) // for socket //
#pragma comment( lib, "tcl85.lib" ) // for C++/TK //
#pragma comment( lib, "tk85.lib" ) // for C++/TK //
// //
#include <tchar.h> // for TCHAR etc. //
#include <tcl.h> // for TCL //
//#include <winsock.h> // //
#include <winsock2.h> // for winsock //
#include <windows.h> // for win32API //
//#include <commdlg.h> // for コモンダイアログ //
#include <stdio.h> // 標準入出力 //
#include <fstream> // ファイルストリーム //
#include <iostream> // 入出力ストリーム //
#include <string> // for string //
//#include <vector> // for vector //
//#include <sstream> // for ostringstream //
#include <wchar.h> // for ワイド文字列 //
#include <stdlib.h> // 標準ライブラリ //
//#include <boost/regex.hpp> // for regex++ //
//#include <stdarg.h> // for vararg //
// //
//#using <mscorlib.dll> // //
// //
using namespace std; // 名前空間 //
//using namespace boost; // 名前空間 //
// //
//extern HINSTANCE vc_hInst; // 外部変数の宣言 //
//extern HWND vc_hWnd; // 外部変数の宣言 //
// //
// 判定用定数定義 //
#define PROC_NG (-1) // プロセスNG //
#define FUNC_NG_NEGATIVE (-1) // 関数NG(-1) //
#define FUNC_NG 0 // 関数NG //
#define END_MSG 0 // 終了メッセージ //
#define PROCESS_OK 0 // 処理OK //
#define RET_OK 0 // リターンOK //
#define RET_NG (-1) // リターンNG //
#define WND_HEIGHT 350 // ウィンドウ高 //
#define WND_WIDTH 570 // ウィンドウ幅 //
#define IND_TRUE 1 // チェック真 //
#define IND_FALSE 0 // チェック偽 //
#define ZERO 0 // そのまま //
#define ONE 1 // そのまま //
#define MINUS_ONE (-1) // そのまま //
#define FFFF 65535 // そのまま //
#define FF 255 // そのまま //
#define IND_DUM (-8) // 偽情報の合言葉 //
// //
// 共通定数定義 //
#define MAX_F_NAME 260 // ファイル名最大文字数 //
// //
// Window定数定義 //
//#define SCRN_POS_X 50 // スクリーンポジションX //
//#define SCRN_POS_Y 50 // スクリーンポジションY //
// //
typedef bool b0; // 変数型別名定義 //
typedef unsigned char u1; // 変数型別名定義 //
typedef signed char s1; // 変数型別名定義 //
typedef unsigned int u4; // 変数型別名定義 //
typedef signed int s4; // 変数型別名定義 //
typedef long f4; // 変数型別名定義 //
typedef double f8; // 変数型別名定義 //
typedef unsigned short u2; // 変数型別名定義 //
typedef signed short s2; // 変数型別名定義 //
typedef int Tcl_PackageInitProc( Tcl_Interp *interp ); // tclインタープリタ //
// //
const f8 ROUND_OFF_RATE = (0.5); // 実数型の整数化に使う値 //
// //
//#include "./StyleDll.h" // StyleDllヘッダファイル //
// //
//using namespace dNet; // //
// //
// //
#endif // COMM_H //
ファイル名:PR_dll.tcl
# HEAD *********************************************************# プログラムに必要な諸々 #
package require Tk ;# パッケージの読込み #
#/HEAD *********************************************************# プログラムに必要な諸々 #
# Namespace PR_DLL *********************************************# 名前空間(PR_DLL) #
namespace eval PR_DLL { ;# 名前空間 #
namespace export * ;# すべてのプロシージャを公開 #
# Dll Test *****************************************************# DLL使用テスト #
proc dllTest {} { ;# #
;# #
# .tBar02.r_msg configure -text "platform = $::tcl_platform(platform)" ;# 確認用 #
switch $::tcl_platform(platform) {
windows { ;# windowsの場合 #
load StyleDll.dll Dlltest ;# 作成したdllをロード #
# load [file join [pwd] StyleDll.dll Dlltest] ;# この方がいいかも #
set interp [Dlltest "Hello"] ;# 登録したTclコマンドを実行 #
} ;# #
unix { ;# unixの場合 #
# load [file join [pwd] libfoo[info sharedlibextension]] ;# とりあえずスルー #
} ;# #
} ;# #
# .tBar02.l_msg configure -text "interp = $interp" ;# 確認用 #
} ;# #
#/Dll Test *****************************************************# DLL使用テスト #
} ;# #
#/Namespace PR_DLL *********************************************# 名前空間(PR_DLL) #
package provide pr_dll 0.01 ;# パッケージとバージョンの宣言 #
*** 修正履歴 [#a1ac3d25]
~
*** 課題 [#e4006fe7]
以下の概念を、管理人自身がいまいち理解してない。~
+Tcl API~
+extern "C"~
~
やりながら覚える。~
ここまで(ロードまで)できればあとはなんとかなる。~
-備考~
初期化関数名に注意が必要です。~
"大文字なんとか_Init" → "load XXXX.dll 大文字なんとか"のカタチじゃなきゃいけないのか?~
Tcl_CreateObjCommandで登録するコマンド名は小文字で始まってもOKです。~
(TclのdllTestと名前が競合するのを避け、また拡張コマンドであることが明示的にもなるため、"大文字なんとか"に統一しています。)~
*** 参考ページ [#z7cd6fa1]
[[Re: How to build a loadable tcl dll with visual studio (microsoftC compiler)?:http://objectmix.com/c/200303-how-build-loadable-tcl-dll-visual-studio-microsoft-c-compiler-crosspost-comp-lang-tcl-comp-lang-c.html]]~
[[なもなも - 簡単なTclコマンドを作るには:http://www.geocities.co.jp/SiliconValley/4137/dir4/tapi28.html]]