如果你看一下这个问题的答案:这里它给出了你需要经历的过程的基本轮廓。我的回答中有一些关于创建 DLL 的 Microsoft MSDN 文章的链接。
更详细地介绍其中嵌入了 Tcl 的 C++ dll。
第一步是创建一个具有正确类型的新 Visual Studio 项目,该项目将构建一个导出符号的 dll。我的示例项目名为 TclEmbeddedInDll,该名称出现在代码中的符号中,例如由 Visual Studio 生成的 TCLEMBEDDEDINDLL_API。
dllmain.cpp 如下所示:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
allocInterp() ;
break ;
}
case DLL_THREAD_ATTACH:
break ;
case DLL_THREAD_DETACH:
break ;
case DLL_PROCESS_DETACH:
{
destroyInterp() ;
break;
}
}
return TRUE;
}
和函数在 TclEmbeddedInDll.h 中定义allocInterp()
,destroyInterp()
这里使用函数而不是直接创建 Tcl_Interp 的原因是它使有关 Tcl 的细节远离 DLL 接口。如果您在此处创建 interp,则必须包含 tcl.h,然后当您尝试在另一个程序中使用 DLL 时,事情会变得复杂。
接下来显示 TclEmbeddedInDll.h 和 .cpp,该函数fnTclEmbeddedInDll()
是从 DLL 导出的函数——我为此使用 C 链接而不是 C++,因为它更容易从其他语言调用函数恕我直言。
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the TCLEMBEDDEDINDLL_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// TCLEMBEDDEDINDLL_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef TCLEMBEDDEDINDLL_EXPORTS
#define TCLEMBEDDEDINDLL_API __declspec(dllexport)
#else
#define TCLEMBEDDEDINDLL_API __declspec(dllimport)
#endif
extern "C" {
TCLEMBEDDEDINDLL_API void fnTclEmbeddedInDll(void);
}
void allocInterp() ;
void destroyInterp() ;
// TclEmbeddedInDll.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
extern "C" {
static Tcl_Interp *interp ;
// This is an example of an exported function.
TCLEMBEDDEDINDLL_API void fnTclEmbeddedInDll(void)
{
int code;
const char *result;
code = Tcl_Eval(interp, "source simple_addition.tcl; add_two_nos");
result = Tcl_GetString(Tcl_GetObjResult(interp));
}
}
void allocInterp()
{
Tcl_FindExecutable(NULL);
interp = Tcl_CreateInterp();
}
void destroyInterp()
{
Tcl_DeleteInterp(interp);
}
allocInterp() 和 destroyInterp() 的实现非常幼稚,没有进行错误检查。
最后,对于 Dll,stdafx.h 文件将它们联系在一起,如下所示:
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// TODO: reference additional headers your program requires here
#include <tcl.h>
#include "TclEmbeddedInDll.h"